← Back to Feed CACHED · 2026-08-24 10:07:44 · CACHE_KEY CVE-2026-75931
CVE-2026-75931 · CWE-436 · Disclosed 2026-07-21

fast-uri vulnerable to host confusion via skipped IDN canonicalization on scheme-relative references

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A Unicode phrasebook that the bouncer reads differently than the bartender, except the bouncer rarely works the door

CVE-2026-13676 (the correct identifier — CVE-2026-75931 does not appear in NVD or GHSA; the title and CVSS you provided match CVE-2026-13676 exactly) affects fast-uri versions 2.3.1–2.4.1, 3.0.0–3.1.2, and 4.0.0. The library's IDN conversion path calls URL.domainToASCII() on the global WHATWG URL constructor, where that helper does not exist. The resulting TypeError is silently swallowed, leaving hostnames in their original Unicode form (e.g. 127。0。0。1 with fullwidth periods). When the same URL is later processed by Node's native URL or fetch(), those consumers normalize the IDN to ASCII (127.0.0.1), creating a parse differential that can bypass host-based allow/deny lists, SSRF loopback filters, or redirect-target validation.

The vendor rates this HIGH 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N), which is defensible *on paper* — the vector is unauthenticated and network-reachable. In practice, this overstates the risk for the vast majority of the 121 M weekly-download install base. fast-uri reaches most Node.js projects through AJV (JSON Schema format: "uri" validation) and Fastify, where it validates whether a string *is* a well-formed URI, not whether that URI is *safe to fetch*. The security-critical scenario — using fast-uri to gate an outbound request before handing the URL to fetch() — is a narrow architectural pattern. Unless your application explicitly calls fast-uri.parse() or fast-uri.equal() as a security control and then passes the same string to a different URL consumer, the parsing differential has no exploitable consequence.

"Parsing differential matters only when fast-uri gates security policy — most installs just validate JSON Schema URIs."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Identify a fast-uri–gated security check

The attacker profiles a target Node.js application and discovers it uses fast-uri (directly or via a custom SSRF-protection middleware) to validate or filter user-supplied URLs before making server-side HTTP requests. This is the critical prerequisite — if the app uses fast-uri only through AJV schema validation, the chain stops here.
Conditions required:
  • Target application uses fast-uri for host-based security enforcement (SSRF filter, redirect validation, or proxy routing)
  • Application passes the same raw URL string to a second parser (Node WHATWG URL, fetch, axios) after the fast-uri check
Where this breaks in practice:
  • Most fast-uri consumers inherit it via AJV/Fastify for JSON Schema validation, not security policy enforcement
  • Enterprise SSRF protections typically use dedicated libraries (ssrf-req-stream, ssrf-agent) or WAF rules, not raw URI parsers
  • Identifying the internal URI-validation stack requires source access or very targeted fuzzing
STEP 02

Craft a Unicode-confusable URL

The attacker constructs a URL using Unicode characters that fast-uri leaves un-normalized but Node's URL normalizes. The canonical example is http://127。0。0。1/internal-api using fullwidth periods (U+FF0E). fast-uri sees host 127。0。0。1 (not on the blocklist); Node's new URL() resolves it to 127.0.0.1 (loopback). Other IDN confusables targeting internal hostnames work similarly.
Conditions required:
  • Application accepts user-supplied URLs containing Unicode characters (not stripped or rejected upstream)
  • The blocklist/allowlist comparison uses fast-uri's parsed host, not the downstream consumer's resolved host
Where this breaks in practice:
  • Many applications percent-encode or reject non-ASCII characters in URL inputs before they reach the URI parser
  • WAFs with Unicode normalization rules catch fullwidth-period tricks
  • Content-type and input validation middleware in Express/Fastify often strips non-ASCII from URL-type fields
Detection/coverage: Semgrep rules for SSRF pattern detection; custom unit tests comparing fast-uri.parse().host against new URL().hostname
STEP 03

Bypass host filter and reach internal resource

The crafted URL passes fast-uri's host check (the Unicode host doesn't match the blocklist entry for 127.0.0.1 or metadata.google.internal). The application then calls fetch() or http.request() with the original URL string, which Node's URL parser normalizes to the blocked destination. The attacker achieves SSRF to the loopback interface, cloud metadata endpoint, or other internal host.
Conditions required:
  • The internal resource responds with sensitive data or allows further pivoting
  • Network-level controls (egress firewall, metadata endpoint IMDSv2 token requirement) do not block the request independently
Where this breaks in practice:
  • Cloud providers' IMDSv2 (AWS) requires a PUT-based token exchange that most SSRF payloads can't complete via simple GET redirect
  • Network segmentation and egress firewalls independently block loopback and metadata access from application pods
  • Even successful SSRF typically yields read-only access to metadata or internal APIs, not RCE
Detection/coverage: Cloud metadata access alerts (GuardDuty, GCP Security Command Center); WAF SSRF signatures; network flow logs showing app-tier → 169.254.169.254
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNo known exploitation. Not listed on CISA KEV. No campaigns or threat-actor usage reported as of 2026-08-24.
Proof of conceptThe GHSA advisory includes a minimal reproduction (http://127。0。0。1/). No weaponized exploit tool or scanner plugin has been published.
EPSS scoreNot yet scored or below reporting threshold — typical for library-level parsing differentials with no observed exploitation.
KEV statusNot listed. No due date.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N — Network/no-auth/no-interaction. Integrity-only impact (no confidentiality or availability). Scope unchanged.
Affected versionsfast-uri 2.3.1–2.4.1, 3.0.0–3.1.2, 4.0.0
Fixed versions2.4.2, 3.1.3, 4.0.1 (latest mainline is 4.1.3 as of 2026-08-23)
Exposure population121 M+ weekly npm downloads, but the vast majority flow through AJV for schema validation. The subset using fast-uri for security-critical host filtering is estimated at <1% of consumers. No Shodan/Censys/GreyNoise exposure surface — this is a library, not a listening service.
Disclosure date2026-07-21 (GHSA published)
Reporter / creditFastify security team (advisory author). No external researcher credited.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.3/10)

The single most decisive factor is the extremely narrow exploitable population: fast-uri is overwhelmingly consumed through AJV for JSON Schema format validation, where the IDN parsing differential has zero security consequence — only the rare application that uses fast-uri as an SSRF or redirect filter *and* then passes the raw URL to a second parser is affected. This narrows the realistic attack surface to well under 1% of the 121 M weekly-download install base, making the vendor's HIGH 7.5 an overstatement for fleet-wide prioritization.

HIGH Vulnerability mechanics and affected versions
HIGH Exploitability assessment (narrow application pattern)
MEDIUM Installed-base share estimate for security-critical usage (<1%)

Why this verdict

  • Narrow exploitable pattern: The vulnerability only fires when fast-uri is used as a security gate (SSRF filter, redirect validator) AND the same raw URL is passed to a different parser downstream. AJV schema validation — the dominant use case — is not affected.
  • No active exploitation or weaponization: No KEV listing, no known campaigns, no scanner plugins, no weaponized PoC beyond the advisory's one-liner example.
  • Multiple independent mitigations exist: IMDSv2 token requirements, egress firewalls, WAF Unicode normalization, and input sanitization all independently break the chain before the parsing differential matters.
  • Role multiplier: fast-uri is a utility library, not an identity provider, hypervisor, or network edge appliance. Even in the worst-case SSRF scenario, blast radius is confined to the compromised application's network context (read-only metadata or internal API access). No plausible chain leads to domain takeover, fleet compromise, or supply-chain pivot. The high-value-role floor does not apply.

Why not higher?

The vendor's HIGH rating would be justified if the majority of fast-uri consumers used it to enforce host-based security policy. They do not — AJV schema validation is the dominant path, and that path is unexploitable. There is no active exploitation, no KEV listing, and the parsing differential alone does not grant RCE or persistent access.

Why not lower?

A LOW or IGNORE rating would understate the risk for the minority of applications that *do* use fast-uri for SSRF protection. In that specific (if rare) architecture, the bypass is unauthenticated, network-reachable, and requires no user interaction — a clean SSRF vector. The 121 M download footprint means even <1% is a non-trivial absolute number of affected applications.

05 · Compensating Control

What to do — in priority order.

  1. Audit your codebase for direct fast-uri security usage — Search for require('fast-uri') or import.*fast-uri calls that feed into host comparisons, blocklist checks, or URL validation before outbound requests. If you only consume fast-uri through AJV/Fastify schema validation, this CVE has no security impact on your application and patching is routine hygiene within the noisgate 365-day remediation window.
  2. Normalize URLs with Node's native URL constructor before policy checks — If you do use fast-uri for security filtering, add new URL(userInput).hostname as the canonical host source for blocklist comparison, ensuring IDN normalization happens before the security decision. This eliminates the parsing differential regardless of fast-uri version.
  3. Enforce IMDSv2 and egress firewalls — Block SSRF impact independently: require IMDSv2 token exchange on AWS (PUT-based, defeats simple GET SSRF), and enforce egress firewall rules that prevent application pods from reaching 169.254.169.254, loopback, and internal management planes.
  4. Upgrade fast-uri to patched version — Update to fast-uri 2.4.2, 3.1.3, or 4.0.1+ in your lockfile. This is a non-breaking patch for each major line. No noisgate mitigation SLA applies at MEDIUM — go straight to the 365-day remediation window.
What doesn't work
  • Stripping non-ASCII from all URL inputs — this breaks legitimate internationalized URLs and may cause application errors for users with IDN domains. It is a blunt-force workaround, not a surgical fix.
  • Relying solely on WAF SSRF signatures — most WAF rulesets check for 169.254.169.254 and localhost in the raw URL but do not perform Unicode normalization, so the fullwidth-period bypass may evade them unless the WAF has explicit IDN handling.
06 · Verification

Crowdsourced verification payload.

Run on any machine with Node.js 18+ and a package-lock.json or node_modules directory. Execute from the project root: bash check_fast_uri.sh. No special privileges required.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_fast_uri.sh — Detect CVE-2026-13676 (fast-uri IDN host confusion)
# Run from the root of a Node.js project.
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

# Try to find fast-uri version from package-lock.json first
if [ -f package-lock.json ]; then
  VERSION=$(node -e "
    const lock = require('./package-lock.json');
    const pkgs = lock.packages || {};
    const deps = lock.dependencies || {};
    const entry = pkgs['node_modules/fast-uri'] || deps['fast-uri'];
    if (entry) console.log(entry.version);
    else console.log('NOT_FOUND');
  " 2>/dev/null || echo 'NOT_FOUND')
elif [ -d node_modules/fast-uri ]; then
  VERSION=$(node -e "console.log(require('fast-uri/package.json').version)" 2>/dev/null || echo 'NOT_FOUND')
else
  VERSION='NOT_FOUND'
fi

if [ "$VERSION" = 'NOT_FOUND' ]; then
  echo "UNKNOWN — fast-uri not found in this project."
  exit 2
fi

echo "Detected fast-uri version: $VERSION"

# Parse major.minor.patch
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"

VULNERABLE=false

case $MAJOR in
  2)
    # Vulnerable: 2.3.1 — 2.4.1. Fixed: 2.4.2+
    if [ "$MINOR" -eq 3 ] && [ "$PATCH" -ge 1 ]; then VULNERABLE=true; fi
    if [ "$MINOR" -eq 4 ] && [ "$PATCH" -le 1 ]; then VULNERABLE=true; fi
    ;;
  3)
    # Vulnerable: 3.0.0 — 3.1.2. Fixed: 3.1.3+
    if [ "$MINOR" -eq 0 ]; then VULNERABLE=true; fi
    if [ "$MINOR" -eq 1 ] && [ "$PATCH" -le 2 ]; then VULNERABLE=true; fi
    ;;
  4)
    # Vulnerable: 4.0.0. Fixed: 4.0.1+
    if [ "$MINOR" -eq 0 ] && [ "$PATCH" -eq 0 ]; then VULNERABLE=true; fi
    ;;
esac

if $VULNERABLE; then
  echo "VULNERABLE — fast-uri $VERSION is affected by CVE-2026-13676."
  exit 1
else
  echo "PATCHED — fast-uri $VERSION is not affected."
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
For most enterprises, this is routine dependency hygiene, not an emergency. First, determine whether any of your Node.js applications use fast-uri *directly* for SSRF filtering or redirect validation (not just through AJV schema validation). If none do, queue the fast-uri upgrade into your normal dependency-update cycle within the noisgate remediation SLA of 365 days for MEDIUM findings — no mitigation SLA applies. If you *do* have applications using fast-uri as a security gate, add a new URL().hostname normalization step before the host comparison as an immediate compensating control, and bump fast-uri to 2.4.2 / 3.1.3 / 4.0.1+ in the same sprint. There is no active exploitation and no KEV listing, so this does not warrant weekend or after-hours patching.

Sources

  1. GHSA-4c8g-83qw-93j6 — GitHub Security Advisory
  2. CVE-2026-13676 — GitLab Advisory Database
  3. fast-uri on npm
  4. fast-uri — Snyk vulnerability database
  5. fastify/fast-uri GitHub repository
  6. OWASP SSRF Prevention Cheat Sheet
  7. fast-uri package analysis — npmx.dev
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.