diff --git a/CHANGELOG.md b/CHANGELOG.md index 66e1927..d576563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ The release notes tracked in this document are also made available on the [releases page](https://github.com/medialize/URI.js/releases) +### master ### + +* **SECURITY** fixing [`URI.parse()`](http://medialize.github.io/URI.js/docs.html#static-parse) handle excessive slashes in scheme-relative URLs - disclosed by [zeyu2001](https://github.com/zeyu2001) via https://huntr.dev/ + ### 1.19.10 (March 5th 2022) ### * **SECURITY** fixing [`URI.parse()`](http://medialize.github.io/URI.js/docs.html#static-parse) handle excessive colons in protocol delimiter - disclosed by [huydoppa](https://github.com/huydoppa) via https://huntr.dev/ diff --git a/src/URI.js b/src/URI.js index f488e8f..c46352b 100644 --- a/src/URI.js +++ b/src/URI.js @@ -518,6 +518,8 @@ // slashes and backslashes have lost all meaning for the web protocols (https, http, wss, ws) string = string.replace(/^(https?|ftp|wss?)?:+[/\\]*/i, '$1://'); + // slashes and backslashes have lost all meaning for scheme relative URLs + string = string.replace(/^[/\\]{2,}/i, '//'); // extract protocol if (string.substring(0, 2) === '//') { diff --git a/test/urls.js b/test/urls.js index ec6da7c..d8c32ef 100644 --- a/test/urls.js +++ b/test/urls.js @@ -581,6 +581,55 @@ var urls = [{ idn: false, punycode: false } + }, { + name: 'ignoring scheme excessive slashes', + url: ':/\\//user:pass@example.org:123/some/directory/file.html?query=string#fragment', + _url: '//user:pass@example.org:123/some/directory/file.html?query=string#fragment', + parts: { + protocol: null, + username: 'user', + password: 'pass', + hostname: 'example.org', + port: '123', + path: '/some/directory/file.html', + query: 'query=string', + fragment: 'fragment' + }, + accessors: { + protocol: '', + username: 'user', + password: 'pass', + port: '123', + path: '/some/directory/file.html', + query: 'query=string', + fragment: 'fragment', + resource: '/some/directory/file.html?query=string#fragment', + authority: 'user:pass@example.org:123', + origin: 'user:pass@example.org:123', + userinfo: 'user:pass', + subdomain: '', + domain: 'example.org', + tld: 'org', + directory: '/some/directory', + filename: 'file.html', + suffix: 'html', + hash: '#fragment', + search: '?query=string', + host: 'example.org:123', + hostname: 'example.org' + }, + is: { + urn: false, + url: true, + relative: false, + name: true, + sld: false, + ip: false, + ip4: false, + ip6: false, + idn: false, + punycode: false + } }, { name: 'scheme-relative URL', url: '//www.example.org/', @@ -629,6 +678,55 @@ var urls = [{ idn: false, punycode: false } + }, { + name: 'scheme-relative URL excessive slashes', + url: '//\\/www.example.org/', + _url: '//www.example.org/', + parts: { + protocol: null, + username: null, + password: null, + hostname: 'www.example.org', + port: null, + path: '/', + query: null, + fragment: null + }, + accessors: { + protocol: '', + username: '', + password: '', + port: '', + path: '/', + query: '', + fragment: '', + resource: '/', + authority: 'www.example.org', + origin: 'www.example.org', + userinfo: '', + subdomain: 'www', + domain: 'example.org', + tld: 'org', + directory: '/', + filename: '', + suffix: '', + hash: '', + search: '', + host: 'www.example.org', + hostname: 'www.example.org' + }, + is: { + urn: false, + url: true, + relative: false, + name: true, + sld: false, + ip: false, + ip4: false, + ip6: false, + idn: false, + punycode: false + } }, { name: 'missing authority', url: 'food:///test/file.csv',