A WAF rule matches the exact payload from one incident report — what does an attacker send instead, and what does widening it cost?
answer
- the rule encodes one spelling
- representation, location, path
- body the rule was never scoped to
- enumeration never converges
- a false positive here rejects partner traffic
basics
~20 sA rule built from one captured sample encodes the attacker's spelling, not the bug. The same input re-encoded, moved into a body the proxy does not parse, split across parameters or sent to another route gets through. Widening the pattern buys false positives on partner traffic you cannot test.
solid answer
~50 sThe rule matches a literal pattern against one parameter after whatever decoding the proxy performs. So the cheap variations are all about staying outside that pipeline: change the encoding or the case, insert whitespace or comment characters the application tolerates and the pattern does not, move the value from the query string into a JSON or multipart body the rule was never scoped to, use a content type the proxy does not decode, exceed the body size the proxy inspects, or find a second route or method that reaches the same handler. None of these touch the bug; they route around the one spelling you wrote down. The instinct is to add each new variation to the pattern, and that is where the price lands: every broadening raises the chance of rejecting real partner traffic — a supplier's free-text field, an XML export, an escaped string in a legitimate payload — on an application you cannot test and a partner you cannot easily roll back for.
go deeper
Know that a rule matches text at a place, not a vulnerability, and that the same input sent in a different encoding or a different part of the request often gets through untouched.
Explain the three families of variation — representation, location, path — and why the proxy's decoding pipeline decides which of them the rule can ever see.
Show judgment about broadening: what you test a widened rule against, how long you watch, and why a rejected partner request is a business incident rather than a tuning nuisance.
Argue for spending effort on the code fix and on closing paths that bypass the proxy, rather than funding an indefinite pattern-chasing exercise nobody can ever declare finished.
## Why one sample is a weak rule When a stopgap rule is written during an incident, it is almost always built from the request that was actually observed. That request is one spelling of one input against one parameter. The rule that comes out of it is a literal match — a string, or a pattern only slightly generalised from it — evaluated against that parameter after the proxy has done its own decoding. The bug is a property of the application. The rule is a property of a string comparison. Those two things have very different shapes, and the gap between them is exactly what an adversary works in. ## Where the variations come from They fall into three families, and it is worth being able to name them rather than list payloads. **Representation.** The same value expressed differently: percent-encoding, double encoding, mixed case, alternative unicode forms, whitespace or comment characters the application's parser tolerates and the pattern does not. If the proxy decodes once and the application decodes twice, everything in between is invisible to the rule. **Location.** The rule is scoped to a parameter in a place. Move the value: from the query string to the request body, from form encoding to JSON, into a multipart part, into a header, or split it across two parameters that the application concatenates. If the rule inspects query arguments only, a body carries the same input straight past it. Content types the proxy does not parse, and bodies larger than the size it will buffer and inspect, are the same problem in another form. **Path.** A different route, a different method, or an alias virtual host that reaches the same handler. The rule is pinned to one route because that is where the incident happened, not because that is where the code is. A competent senior engineer's wrong answer here is *"we tightened the rule after each finding, so it is comprehensive now."* Enumeration does not converge: you are guessing the tail of an infinite set from the handful of samples an attacker chose to let you see. ## What widening costs The rule sits in blocking mode in front of an application whose code you do not own, serving a partner whose traffic you did not design. Every broadening of the pattern is a bet placed on traffic you cannot enumerate: - a partner's free-text comment field that legitimately contains the token you now match; - a supplier's XML or JSON export where an escaped sequence trips the broadened pattern; - a batch submission that runs monthly, so the false positive appears five weeks after the change and is never connected to it. And the false positive here is not an analyst's hour, which is what a detection costs when it is wrong. It is a rejected request: a partner integration failing in production, at a business you have a contract with, on a route you cannot debug from the inside because the application is not yours. There is a second, slower cost. Each variation you add makes the rule harder to retire. A rule that matched one archived sample has a clear deletion test: does the fixed build reject that sample on its own? A rule that has accreted eleven clauses over four years has eleven deletion tests, some of which correspond to bugs that were never real, and nobody can say which clauses are load-bearing. Widening is how a two-line stopgap becomes an artefact nobody dares touch. ## What to do instead Accept the rule's narrowness explicitly rather than chasing it. Record what it covers and what it plainly does not, and spend the effort on the two things that actually converge: getting the code fixed by the party that owns it, and reducing the paths that reach the application without passing the proxy. If you must broaden, broaden by **scope** rather than by **pattern** — inspect the body as well as the query on that route, decode consistently, cap what you accept on that parameter by type and length — because scope changes are testable and explainable, while an ever-growing pattern is neither. Most importantly, when you add a variation, add it with the same bookkeeping as the original: what sample justified it, and what would prove it redundant. Otherwise the widening is invisible work that only makes the deletion harder.
- Why is broadening the rule's scope safer than broadening its pattern?Scope changes are testable and explainable: inspecting the body as well as the query on that route, decoding consistently, or constraining the parameter by type and length are statements you can validate against known-good partner traffic. A pattern that grows a clause per incident is a guess about an infinite set, and each clause makes the eventual deletion harder because nobody knows which ones matter.
- The rule is scoped to query arguments and the application also accepts a JSON body. What have you actually deployed?A rule covering one of at least two doors into the same handler. The application decides which inputs it reads; the rule only sees what it was scoped to parse. Before trusting a pinned rule you confirm every content type and parameter location the route accepts, otherwise the stopgap protects the path the incident happened to use and nothing else.
- A partner's monthly batch submission starts failing after you widened the rule. Why is this hard to attribute?The change and the failure are weeks apart, the traffic is rare enough that no test window would have covered it, and the failing request is rejected at the proxy so the application logs show nothing at all. This is why an observation period on a broadened rule must span the rarest legitimate flow, and why blocking mode on a partner integration is a decision with a business owner.
saying these in an interview costs you the question
- Claims the rule covers the bug because it matched the exploit
- Adds a clause per incident and calls the pattern comprehensive
- Forgets the request body, alternate content types and other routes
- Treats a WAF false positive as costing only an analyst's time
- Widens the rule without recording what justified each clause