CVE-2026-18174
The vendor's framing of this as a low-severity issue misses the actual threat model. The vulnerability isn't that tab-corrupted IP strings 'look like' trusted proxies — it's that a single tab byte (0x09) embedded in an IP creates a unique identifier that most downstream consumers cannot correlate with the attacker's clean IP, while still being accepted as a valid string by security mechanisms that don't enforce strict IP format validation. The advisory argues that malformed IPs won't match allowlists, so what's the harm? This reasoning only holds if downstream applications re-validate IP format before using it in security decisions. In practice, that's a fragile assumption that almost nobody meets. Rate limiting implementations in particular often hash or prefix the raw resolved address directly into Redis or memory keys without re-checking format — they trust the library's output. Express-rate-limit and similar libraries use the resolved IP as a key without format validation, a pattern visible in their source. An attacker who can inject a tab into any X-Forwarded-For position can generate a unique client identifier that bypasses rate limits while evading correlation with their clean IP in logs. The deeper issue: parsing libraries at trust boundaries should be strict by default, not lenient with ambiguous output. RFC 7230 defines optional whitespace explicitly as HTAB | SP. A parser that strips one but not the other is making a silent format decision that downstream code cannot anticipate. Security-sensitive libraries should either return canonicalized output (always strip both) or return an error for malformed input, not leave garbage bytes in the resolved string. Worse, this creates a persistent bifurcation across your monitoring stack. Your SIEM drops the malformed string, your WAF ignores it, your rate limiter generates a new key, your audit log writes it as a new entity. The attacker gets clean passage through security controls while your forensic tooling loses correlation entirely. You don't have a single vulnerability — you have a single injection point that simultaneously evades detection, defeats correlation, and leaves no traceable artifact tying the attacker's tab-padded request back to their clean IP. This is likely systemic across the Node.js HTTP parsing ecosystem. The underlying node-module ecosystem for X-Forwarded-For parsing shows inconsistent tab handling — some use regex stripping, others don't. The API makes the dangerous thing feel safe: developers delegate IP parsing to @fastify/forwarded and trust its output as a string, never expecting garbage bytes.
Reviewed through automated stages and approved by a human before publication.