{"schema":"threatline.record/2","record":{"id":"GHSA-2rg9-wxfw-wrr7","aliases":["GHSA-2rg9-wxfw-wrr7"],"summary":"@pdfme/common: isUrlSafeToFetch bypass via IPv4-mapped IPv6, [::] and localhost. (incomplete fix of GHSA-pgx6-7jcq-2qff)","details":"### Summary\n\nThe fix for GHSA-pgx6-7jcq-2qff added `isUrlSafeToFetch`, which `getB64BasePdf` calls before `fetch(basePdf)`. It is a string denylist on `new URL(x).hostname`. WHATWG URL normalises IPv4-mapped IPv6 to hex (`new URL('http://[::ffff:127.0.0.1]/').hostname === '[::ffff:7f00:1]'`), so the dotted-quad mapped-address check never matches. `[::]`, NAT64 and trailing-dot `localhost.` are not covered either.\n\n### Affected\n\n@pdfme/common 6.2.5 (latest), `isUrlSafeToFetch` / `getB64BasePdf` in `dist/index.js` (around lines 436-467 and 597-600).\n\n### Reproduction\n\nnode 22, Docker with `--network none`, calling the exported `isUrlSafeToFetch`:\n\n```\nhttp://127.0.0.1/              false\nhttp://169.254.169.254/        false\nhttp://[::ffff:127.0.0.1]/     true\nhttp://[::ffff:7f00:1]/        true\nhttp://[::ffff:a9fe:a9fe]/     true   (169.254.169.254, cloud metadata)\nhttp://[::]/                   true\nhttp://localhost./             true\n```\n\nThe plain loopback and metadata addresses are rejected (control). Their IPv4-mapped forms, `[::]` and `localhost.` are reported safe and would be fetched.\n\n### Impact\n\nSame scenario as GHSA-pgx6-7jcq-2qff: an attacker who controls a template's `basePdf` makes the runtime fetch internal URLs, including cloud metadata, and the response is embedded as the base PDF. The fetch runs where `window` is defined (browser or a server-side DOM shim). Estimated CVSS 3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N.\n\n### Suggested fix\n\nParse the hostname with an IP library, unwrap IPv4-mapped and NAT64 addresses to IPv4, reject every non-global address (including `::` and `0.0.0.0/8`), and strip a trailing dot before comparing hostnames.\n\nFound with AploSec.\n\nReported by Zachariah Mithani (zachariah@aplosai.com).","categories":["Unclassified"],"product":"@pdfme/common","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/pdfme/pdfme/security/advisories/GHSA-2rg9-wxfw-wrr7","source_modified_at":"2026-10-16T01:30:00Z","fetched_at":"2026-10-24T23:06:24.700873Z","package":{"ecosystem":"npm","name":"@pdfme/common"},"range":">= 5.5.10, < 6.2.6"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/pdfme/pdfme/security/advisories/GHSA-2rg9-wxfw-wrr7","source_modified_at":"2026-10-16T01:30:00Z","fetched_at":"2026-10-24T23:06:24.700873Z","package":{"ecosystem":"npm","name":"@pdfme/common"},"version":"6.2.6"}],"cvss":3.7,"severity":"Low","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-16T01:30:00Z","modified_at":"2026-10-16T01:30:00Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/pdfme/pdfme/security/advisories/GHSA-2rg9-wxfw-wrr7","fetched_at":"2026-10-24T23:06:24.700873Z","source_modified_at":"2026-10-16T01:30:00Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-16T01:30:00Z","content_hash":"312ba8b8e40e58768021c5d9bdc1c9b543dff94155566910bae03cbc37cff5a9"}}
