VYPR
Moderate severityNVD Advisory· Published Jul 16, 2021· Updated Aug 3, 2024

Open Redirect in medialize/URI.js

CVE-2021-3647

Description

URI.js is vulnerable to URL Redirection to Untrusted Site

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

URI.js before 1.19.11 parses URLs with backslashes or single slashes in a way that can lead to open redirect.

Vulnerability

URI.js, a JavaScript URI parsing library, is vulnerable to URL redirection to untrusted sites due to improper parsing of URLs containing backslashes or single slashes in the protocol scheme. Affected versions are prior to 1.19.11 [1]. Specifically, the library incorrectly interprets URLs like https:/\/\/attacker.com, https:attacker.com, or https:/attacker.com as having hostname attacker.com, instead of treating the attacker.com as a path component [1]. This allows a crafted URL to bypass validation that relies on URI.js to parse and check the target host.

Exploitation

An attacker can exploit this vulnerability by crafting a URL that uses a backslash or a missing double slash after the scheme (e.g., https:attacker.com). If a web application uses URI.js to parse user-supplied URLs and subsequently redirects the user to the parsed hostname, an attacker can trick the application into redirecting to an external (attacker-controlled) site. No authentication or special network position is required; the attacker only needs to deliver the malicious URL to the application (e.g., via a parameter in a link or a redirect endpoint). [1][2]

Impact

Successful exploitation leads to open redirect, where a user visiting a link on a trusted domain is transparently forwarded to an arbitrary external site. This can be used in phishing campaigns, credential theft, or malware distribution, as the initial URL appears legitimate. The trust in the vulnerable application is undermined. [2]

Mitigation

The vulnerability is fixed in URI.js version 1.19.11. Users should update to 1.19.11 or later [1][3]. Earlier versions (including 1.19.3, 1.19.6, etc.) are affected. No known workaround exists other than applying the patch. The issue is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of the latest update.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
urijsnpm
< 1.19.71.19.7

Affected products

2
  • ghsa-coords
    Range: < 1.19.7
  • medialize/medialize/URI.jsv5
    Range: unspecified

Patches

1
ac43ca8f80c0

fix(parse): more backslash galore #410

https://github.com/medialize/URI.jsRodney RehmJul 11, 2021via ghsa
2 files changed · +346 0
  • src/URI.js+3 0 modified
    @@ -512,6 +512,9 @@
           string = string.substring(0, pos);
         }
     
    +    // slashes and backslashes have lost all meaning for the web protocols (https, http, wss, ws)
    +    string = string.replace(/^(https?|ftp|wss?)?:[/\\]*/, '$1://');
    +
         // extract protocol
         if (string.substring(0, 2) === '//') {
           // relative-scheme
    
  • test/urls.js+343 0 modified
    @@ -2131,6 +2131,349 @@ var urls = [{
             idn: false,
             punycode: false
           }
    +    }, {
    +      name: 'backslashes protocol excessive',
    +      url: 'https:/\/\/\attacker.com',
    +      _url: 'https://attacker.com/',
    +      parts: {
    +        protocol: 'https',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'https',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'https://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
    +    }, {
    +      name: 'no slash protocol https',
    +      url: 'https:attacker.com',
    +      _url: 'https://attacker.com/',
    +      parts: {
    +        protocol: 'https',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'https',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'https://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
    +    }, {
    +      name: 'single slash protocol https',
    +      url: 'https:/attacker.com',
    +      _url: 'https://attacker.com/',
    +      parts: {
    +        protocol: 'https',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'https',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'https://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
    +    }, {
    +      name: 'excessive slash protocol https',
    +      url: 'https://////attacker.com',
    +      _url: 'https://attacker.com/',
    +      parts: {
    +        protocol: 'https',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'https',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'https://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
    +    }, {
    +      name: 'no slash protocol ftp',
    +      url: 'ftp:attacker.com',
    +      _url: 'ftp://attacker.com/',
    +      parts: {
    +        protocol: 'ftp',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'ftp',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'ftp://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
    +    }, {
    +      name: 'single slash protocol ftp',
    +      url: 'ftp:/attacker.com',
    +      _url: 'ftp://attacker.com/',
    +      parts: {
    +        protocol: 'ftp',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'ftp',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'ftp://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
    +    }, {
    +      name: 'excessive slash protocol ftp',
    +      url: 'ftp://////attacker.com',
    +      _url: 'ftp://attacker.com/',
    +      parts: {
    +        protocol: 'ftp',
    +        username: null,
    +        password: null,
    +        hostname: 'attacker.com',
    +        port: null,
    +        path: '/',
    +        query: null,
    +        fragment: null
    +      },
    +      accessors: {
    +        protocol: 'ftp',
    +        username: '',
    +        password: '',
    +        port: '',
    +        path: '/',
    +        query: '',
    +        fragment: '',
    +        resource: '/',
    +        authority: 'attacker.com',
    +        origin: 'ftp://attacker.com',
    +        userinfo: '',
    +        subdomain: '',
    +        domain: 'attacker.com',
    +        tld: 'com',
    +        directory: '/',
    +        filename: '',
    +        suffix: '',
    +        hash: '',
    +        search: '',
    +        host: 'attacker.com',
    +        hostname: 'attacker.com'
    +      },
    +      is: {
    +        urn: false,
    +        url: true,
    +        relative: false,
    +        name: true,
    +        sld: false,
    +        ip: false,
    +        ip4: false,
    +        ip6: false,
    +        idn: false,
    +        punycode: false
    +      }
         }, {
           name: '__proto__ in query',
           url: 'http://www.example.org/?__proto__=hasOwnProperty&__proto__=eviltwin&uuid',
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.