CYART // SCHEMA · REQUEST-PATH7 NODES · 6 LINKSLOOKUP1HTTPS234READ / WRITE5HIT FIRSTACTOR · User — browser / appACTOR01Userbrowser / appEDGE · DNS — resolves nameEDGE02DNSresolves nameEDGE · CDN / WAF — TLS ends hereEDGE03CDN / WAFTLS ends hereEDGE · Load balancer — L7, health checksEDGE04Load balancerL7, health checksSERVICE · API service — authn + authzSERVICE05API serviceauthn + authzDATA · Database — primary + replicasDATA06Databaseprimary + replicasDATA · Cache — short TTLDATA07Cacheshort TTL

Design a WAF rule engine

Design the core of a web application firewall: normalise requests the way the backend will read them (decoding layers, Unicode, paths, duplicate parameters), run rules by phase with transformation chains, add up a CRS-style anomaly score with paranoia levels, fail closed on what cannot be parsed, and stay inside a latency budget.

● Hard🔒 PRODesign problem·36 min read·Advanced → Staff
WAFModSecurityOWASP CRSanomaly scoringparanoia levelWAF bypass

01Understand the problem

✓What you will learn
  • Normalise a request so the WAF sees what the application will see, including double encoding, %uXXXX, fullwidth Unicode and Tomcat ..;/ paths
  • Run rules in phases with transformation chains and memoise the work
  • Use anomaly scoring (CRS: critical 5, error 4, warning 3, notice 2; threshold 5) instead of block-on-first-match
  • Separate blocking and detection paranoia levels so stricter rules can be trialled in log-only mode
  • Name the bypass classes and which design choice closes each
◎Interview radar

What they probe: whether you understand that most WAF bypasses are parser differentials (the WAF and the app read different bytes), how anomaly scoring and paranoia levels trade false positives for coverage, what happens to a body that will not parse or is too large, and how you keep regex cost bounded. Where candidates slip: matching on the raw URL, decoding with a function that throws, skipping inspection on parse errors, JavaScript regexes with nested quantifiers on attacker input.

A WAF (web application firewall) sits in front of an application and inspects HTTP requests for attack payloads. ModSecurity is the classic engine and the OWASP Core Rule Set (CRS) the classic rule set. In ModSecurity, rules run in five phases: 1 request headers, 2 request body, 3 response headers, 4 response body, 5 logging. This design covers phases 1 and 2.

  1. evaluate(request) returns allow or block with a score, every match and a reason.
  2. Each rule names a phase, targets (path, args, headers, cookies, body args), a transformation chain, an operator (regex or phrase list), a severity and a paranoia level.
  3. Matches add severity points; the request is blocked when the inbound score reaches the threshold.
  4. Rules above the blocking level but within the detection level run and log without scoring.
  5. Anything the engine cannot inspect faithfully (unparseable body, oversize body, duplicate Content-Type, too many args) is blocked.
BudgetValueConsequence
Added latencyp99 under 1 ms of CPU per requestMemoise transforms; prefilter phrases; cap body bytes
Rulesabout 200 at PL1, 400+ at PL4Most rules see a handful of targets; a phrase prefilter skips most regexes
Body inspection8 KiB here (AWS WAF on an ALB inspects the first 8 KB by default)Bytes past the limit are a policy decision, never silently ignored
Args255 per requestBounded work per request whatever the attacker sends

This is an advanced module

Problems: detection & enforcement components is part of the Pro pass. 4 more sections — the deep dives, the final design, follow-ups and the test — unlock with it.

Already a cyart.io or studio.cyart.io member? Your pass code is in your Studio account.