Open Redirect in tjenkinson/url-toolkit
Reported on
Jul 8th 2021
✍️ Description
url-toolkit
mishandles certain uses of backslash such as https:/\ and interprets the URI as a relative path. Browsers accept backslashes after the protocol, and treat it as a normal slash, while url-toolkit sees it as a relative path. Which will lead to SSRF attacks, open redirects, or other undesired behavior.
Similar to CVE-2021-27515, CVE-2021-27516
🕵️♂️ Proof of Concept
- Create the following PoC file:
// poc.js
var urlToolkit = require("url-toolkit")
var u= urlToolkit.parseURL("https:/\/\/\github.com/foo/bar")
console.log(u)
- Execute the following commands in another terminal:
npm i url-toolkit # Install affected module
node poc.js # Run the PoC
- Check the Output:
{
scheme: 'https:',
netLoc: '//',
path: '/github.com/foo/bar',
params: '',
query: '',
fragment: ''
}
💥 Impact
Depending on library usage and attacker intent, impacts may include allow/block list bypasses, SSRF attacks, open redirects, or other undesired behavior.
Occurrences
Thanks!
I will try and take a look at this later. If not hopefully this weekend.
Tom
There is definitely an issue here but it's not related to \
I think. The problem is just having a url like https:///github.com/foo/bar
, which results in netLoc
being //
.
Looks like Chrome will convert an http:///////example.com/
to http://example.com
I'm wondering if we should throw an error if netLoc
is empty or if netLoc
should be http://////
in the above case
I just released https://github.com/tjenkinson/url-toolkit/releases/tag/v2.2.3 which documents the difference between "URL Living Standard" and "RFC 1808". I don't think it's a bug given it's the correct result according to that RFC (if I've understood correctly).
Also the description here is not quite right. It's not an issue related to backslash, but too many forward slashes.
Thanks for reporting. If there's more of an issue here and I misunderstood please let me know.
Tom
The library implements "RFC 1808", and not "URL Living Standard", and I think the output is valid with respect to "RFC 1808".
I've done a new release to document this difference in the readme.
Well it was a doc update as mentioned above and this was a reference to that...