HarperFast / HarperFast/harper-pro
A WAF rule written with an IPv4-mapped IPv6 address compiles but can never match
- Dominant language
- JavaScript
- Stars
- 3
- Forks
- 0
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 80
Description
Request IPs and rule anchors are normalized differently, so a rule written with an IPv4-mapped IPv6 literal never matches the client it names.
Request side, `normalizeIp` in `waf/matcher.ts`:
```
if (ip.startsWith('::ffff:') && ip.indexOf('.') !== -1) return ip.slice(7);
```
The mapped form is stripped to a dotted quad, which then resolves through `parseIpv4` and is matched against the v4 interval index only.
Rule side, `parseAnchor` applies no such normalization: `parseIpv4('::ffff:1.2.3.4')` fails on the colons, `parseIpv6` succeeds, and the anchor is staged into `v6Exact`. Nothing ever consults `v6Exact` for a request whose address was normalized to v4.
Net effect: `ip: "::ffff:203.0.113.9"` compiles into a rule that can never fire, with no error — it is a valid v6 anchor as far as the compiler is concerned. `ip: "203.0.113.9"` works. Which form an operator reaches for depends on which form they saw in a log or an upstream header, so this is a coin flip at authoring time, not an exotic input.
**Suggested fix:** run rule anchors through the same normalization as request addresses before `parseAnchor` decides v4 vs v6, so both sides share one canonical space. `normalizeIp` already carries a `TODO(M5)` about handling the full `::ffff:0:0/96` range rather than only the canonical lowercase form; the rule side needs whatever that resolves to as well.
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
Research direction
Start in waf/matcher.ts by reading normalizeIp and tracing how parseAnchor classifies rule addresses into the v4 and v6 indexes. Confirm the current behavior with an IPv4-mapped IPv6 rule and request address, then make both paths use the same canonical form. Done means the mapped rule matches the named client without changing the working dotted-quad case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100