nuxt-og-image SSRF — bypass of GHSA-pqhr-mp3f-hrpp / v6.2.5 fix (IPv6 + redirect)
Date: 2026-05
Affected: npm/nuxt-og-image
Attack vector: ssrf
Category: vulnerability-disclosure
Severity: Low
CVE: CVE-2026-44589
CWE: CWE-918
CVSS: 3.7 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N)

## Summary The `isBlockedUrl()` denylist introduced in `nuxt-og-image@6.2.5` to remediate **GHSA-pqhr-mp3f-hrpp** (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. The patch advisory states "Decimal/hexadecimal IP encoding bypasses are also handled" — that part is true (Node's WHATWG URL parser canonicalizes those forms before validation), but the v6.2.5 implementation misses two independent surfaces in the latest release `6.4.8`: 1. **IPv6 prefix list is incomplete.** The IPv6 branch checks only `bare === "::1" || startsWith("fc") || startsWith("fd") || startsWith("fe80")`. It misses: - `[::ffff:7f00:1]` — IPv6-mapped IPv4 loopback in pure-hex form (RE_MAPPED_V4 regex requires dotted-quad). **Reaches 127.0.0.1 on a single-stack-IPv4 host with no other primitive needed.** - `[fec0::/10]` (RFC 3879 site-local — deprecated but still routable on legacy networks) - `[5f00::/16]` (RFC 9602 SRv6 SIDs) - `[3fff::/20]` (RFC 9637 IPv6 documentation v2) - `[64:ff9b:1::/48]` (RFC 8215 NAT64 local-use, including embedded IPv4 loopback `[64:ff9b:1::7f00:1]`) 2. **No redirect re-validation.** `isBlockedUrl` runs once on the initial `<img src>`. The subsequent `$fetch(decodedSrc, ...)` (ofetch, default redirect-follow) follows 30x responses with no second-pass validation. Any allowed origin that returns a 302 to an internal IP — S3 redirect rules, GCS, Azure, CloudFront, any user-content CDN where the attacker can place a single redirect — completes the


Mitigations:

Architectural layers (MAESTRO):