HarperFast / HarperFast/harper-pro
WAF rules using reserved features are accepted and reported as added, then compiled out unenforced
- Dominant language
- JavaScript
- Stars
- 3
- Forks
- 0
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 80
Description
`add_waf_rule` and `alter_waf_rule` validate a rule with `validateRule` and persist it, returning `Added WAF rule `. Whether the v1 engine will actually *enforce* that rule is decided by a different function — `deferralReasons` in `waf/matcher.ts` — which only `compileRules` calls.
A rule using any of `action: challenge|serve|drop`, `match.ja4`, `match.ja4h`, `match.model`, `match.agent`, or `rateLimit` validates cleanly, is stored, is reported as added, and is then compiled out entirely. `waf/matcher.ts` is explicit that this is by design: "any single deferred feature removes the whole rule from the matcher". `waf/rules.ts` says the same: "A rule can validate cleanly yet use a reserved/unimplemented feature".
The design is fine; the missing signal is not. The operator who adds a `rateLimit` rule has no way to learn from the operation response that nothing will enforce it. The compiler does report it through `onUnsupportedRule` into the log summary, so the information exists — it just never reaches the caller.
The sharper case is `alter_waf_rule`: patching `rateLimit` onto a rule that is currently enforced silently moves it from enforced to deferred, with a success response.
**Suggested fix:** have `add_waf_rule`/`alter_waf_rule` call `deferralReasons` and return the reasons in the response (`{ message, deferred: [...] }`), and surface the same on `list_waf_rules`. Rejecting is probably wrong — persisting reserved-feature rules ahead of the engine is the stated intent — but reporting is not optional.
Found by cross-model review while reviewing an unrelated change; not customer-reported.
Contributor guide
Research direction
Start in waf/rules.ts with add_waf_rule, alter_waf_rule, and list_waf_rules, then read deferralReasons and compileRules in waf/matcher.ts. Trace how onUnsupportedRule reaches the log summary and identify the operation response path. Done means reserved-feature rules remain persistable while add, alter, and list responses expose their deferral reasons, including when alter makes an enforced rule deferred.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100