HarperFast / HarperFast/harper-pro

WAF path and query matching decode to different depths, so an escaped payload normalizes on one and not the other

Open
#831 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
3
Forks
0
Avg merge
1d 21h
Merged PRs (30d)
80

Description

Path matching and query matching canonicalize to different decode depths, so the same escaped payload is normalized on one surface and not the other.

`canonicalizePath` in `waf/matcher.ts` decodes iteratively, up to two passes:

```
for (let pass = 0; pass < 2; pass++) { ... next = decodeURIComponent(decoded); ... }
```

The query-string parser in the same file decodes each name and value exactly once.

So a value arriving as `%2527` becomes `%27` for query matching and `'` for path matching. A rule written against the decoded form matches in a path and misses in a query. An application that itself decodes twice — or a framework that does — sees `'`, which is the form the rule was written for.

This is only a mismatch, not a claim that a single decode is wrong: it is the *asymmetry* that is the defect, because a rule author has no way to know which surface they are on. `canonicalizePath`'s own doc comment states the intent for the path side — "so encoding- and traversal-based evasions ... can't slip past a path rule" — and the query side does not meet it.

**Suggested fix:** share one canonicalization routine between the two, with the same bounded iteration count, and document the decode depth as part of the rule-authoring contract so a rule author knows what form to write against. Whichever depth is chosen, both surfaces should use it.

Found by cross-model review while reviewing an unrelated change; not customer-reported. The WAF is unreleased — `main` and `v5.3.0-alpha.1` only.

Contributor guide

Open the contributing guide

Research direction

Start in waf/matcher.ts by comparing canonicalizePath with the query-string parser and tracing their current decode behavior. Decide the shared bounded decode depth and document that depth for rule authors; done means identical normalization for equivalent path and query payloads, with coverage added for the differing-depth case.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.