All vulnerabilities
CVE-2026-110306GHSA-w74x-v6f9-j3xg

fast-uri vulnerable to URI scheme spoofing via percent-encoded scheme decoding

fast-uri fast-urinpmLibraries & packages
CVSS
6.1Medium
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)0.20%Chance of exploitation activity in the next 30 days, higher than 9% of CVEs. Scored 23 Oct 2026FIRST EPSS
Fixed in2.4.8Also 3.1.9, 4.2.3GitHub
Published20 Oct 2026Updated 23 Oct 2026CVE List

What fixes it

  • 2.4.8fast-uri, npmGitHubnpm install fast-uri@2.4.8
  • 3.1.9fast-uri, npmGitHubnpm install fast-uri@3.1.9
  • 4.2.3fast-uri, npmGitHubnpm install fast-uri@4.2.3
  • 2.4.8fast-uriCVE List
  • 3.1.9fast-uriCVE List
  • 4.2.3fast-uriCVE List

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Impact

fast-uri percent-decodes the scheme component with the legacy global unescape() before validating it, so an input whose decoded scheme is a valid but dangerous token is emitted as a live scheme. RFC 3986 section 3.1 does not allow percent-encoding in a scheme, so no RFC or WHATWG parser treats such input as having that scheme, but fast-uri does.

For example, normalize('%6Aavascript:alert(1)') returns javascript:alert(1), resolve('https://a.example/', '%6Aavascript:alert(1)') returns javascript:alert(1), and parse('%6Aavascript:alert(1)').scheme returns javascript. The %uXXXX form (%u006Aavascript:) produces the same result, and equal('%68ttp://a/', 'http://a/') returns true.

An application that screens dangerous schemes on the raw input and then stores or renders normalize(input) or resolve(base, input) turns an inert string into an executable javascript:, data:, or vbscript: URL, a stored or reflected cross-site scripting vector in the consuming application. equal() also treats an encoded and a plain scheme as the same, which can bypass equality-based allowlists.

Patches

Upgrade to fast-uri 2.4.8, 3.1.9, or 4.2.3.

Workarounds

Reject input whose scheme part (before the first :, and before any /, ?, or #) contains %. Alternatively, check parse(x).scheme against an allowlist after normalization and use that same parsed result rather than the raw string.

Text from GitHub Advisory Database

Affected versions 12

  • fast-uri, npm< 2.4.8GitHub
  • fast-uri, npm>= 3.0.0, < 3.1.9GitHub
  • fast-uri, npm>= 4.0.0, < 4.2.3GitHub
  • fast-uriaffected: all versions before 2.4.8CVE List
  • fast-uriunaffected: 2.4.8CVE List
  • fast-uriaffected: 3.0.0 before 3.1.9CVE List
  • fast-uriunaffected: 3.1.9CVE List
  • fast-uriaffected: 4.0.0 before 4.2.3CVE List
  • fast-uriunaffected: 4.2.3CVE List
  • fast-uri, npmfrom first release, fixed in 2.4.8OSV
  • fast-uri, npmfrom 3.0.0, fixed in 3.1.9OSV
  • fast-uri, npmfrom 4.0.0, fixed in 4.2.3OSV

References 10