The last time a hostname-confusion bug surfaced in fast-uri, the maintainers patched it. That patch is what created this one. CVE-2026-75899, disclosed on August 23, is a server-side request forgery (SSRF) and allowlist-bypass flaw in fast-uri, the URL parser that Fastify and a long list of other Node.js projects rely on to normalize and resolve web addresses. If your application checks a user-supplied URL against an allowlist before making an outbound request, this bug can quietly send that request somewhere else.
The mechanics are simple, and that is what makes them dangerous. fast-uri decodes percent-encoded characters in the host part of a URL, and in the affected versions it does that decoding twice: once while parsing the address, and again while rebuilding it. So an attacker can encode a hostname, then encode the encoding, and hand your app a string that looks nothing like localhost. Your allowlist sees an unfamiliar, opaque host and waves it through. fast-uri then peels off both layers and resolves it straight back to localhost, or to a cloud provider's metadata endpoint, or to any internal name the attacker picked. A single normalize() or resolve() call is all it takes.
The flaw carries a CVSS score of 7.5, rated high. It needs no authentication and no user interaction: any input path that reaches normalize() or resolve() with an untrusted URL is in scope.
Which versions are affected
Three release lines are affected, each with its own fix. The 2.x, 3.x, and 4.x branches all shipped a patched build.
| Release line | Affected | Fixed in |
|---|---|---|
| 2.x | 2.4.1 through 2.4.4 | 2.4.5 |
| 3.x | 3.1.2 through 3.1.5 | 3.1.6 |
| 4.x | 4.0.0 through 4.1.2 | 4.1.3 |
You may ship fast-uri without knowing
Here is the part most coverage will skip. Almost nobody installs fast-uri on purpose. It rides in as a transitive dependency, most often under Fastify but also under other URL-handling libraries, so the affected population is far larger than the download count for the package alone suggests. The question to answer today is not "do we use fast-uri" but "does anything in our tree pull it in," and for most Node shops the answer is yes. Run npm ls fast-uri and read the resolved version, not the one in your package.json. A direct version bump will not save you if a nested dependency still pins an old copy.
A fix that opened the next hole
This is the second host-confusion problem disclosed in fast-uri in a matter of months, and the advisory is explicit that it is an incomplete fix of CVE-2026-6322, an earlier bypass in the same parser. The earlier remediation changed how percent decoding worked and, in doing so, introduced the second decode that this bug abuses. That pattern is worth sitting with. We saw the same shape in decode-uri-component, another small Node URL utility where the patch never reached most of the apps that needed it, and in N-able N-central, where the first fix for an authentication bypass failed and a second had to follow. URL and URI parsing is deceptively hard: every normalization step is a chance to disagree with the next component about what the address means, and RFC 3986 warns implementations not to decode the same string more than once for precisely this reason.
Why an internal request is worse than it sounds
SSRF is not an abstract category. It is the same primitive behind a long run of cloud breaches, because an application server can usually reach places an outside attacker cannot: the cloud metadata service that hands out temporary credentials, internal admin panels, databases bound to private addresses. We covered the same reach-the-internal-network outcome in Red Hat's Multicluster Engine and in Apache Camel's Solr component. The reason this class keeps working is that the allowlist check and the actual outbound request often run on different views of the URL. If your validator inspects the address before fast-uri finishes decoding it, and your HTTP client acts on the address after, the two never agree, and the gap is invisible in your logs unless you record the final resolved destination.
Update fast-uri, and stop trusting a pre-decode allowlist
Patch first. Move to 2.4.5, 3.1.6, or 4.1.3, whichever branch you are on, and force the resolution so a nested dependency cannot hold you on a vulnerable copy. If you cannot patch immediately, the maintainers publish a workaround: before you hand an untrusted URL to normalize() or resolve(), drop it if its host contains an encoded percent sign, written %25, which is the fingerprint of the double-encoding trick.
Then close the structural gap, because the next parser bug will look just like this one. Validate the destination after normalization, not before, and better still, enforce the allowlist at the point the connection is actually made rather than trusting a string check upstream. On the detection side, the signal is egress: an application server opening a connection to a loopback, link-local, or cloud-metadata address right after it handled a user-supplied URL. Alerting on outbound requests from app servers to internal ranges catches this whether the entry point is fast-uri today or the next double-decode tomorrow, which is the kind of behavior a managed detection setup should flag by default.
There is no evidence yet that anyone is exploiting this in the wild, and it is not on CISA's known-exploited list. That is the window. A double-decode SSRF in a parser this widely embedded will not stay theoretical for long, and the fix is a version bump. The teams that get burned will be the ones who never realized they were running it.