Package: release.debian.org Severity: normal Tags: bullseye User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: node-url-pa...@packages.debian.org Control: affects -1 + src:node-url-parse
[ Reason ] node-url-parse is vulnerable to authorization bypass through user-controlled key prior version 1.5.6 [ Impact ] Medium security issue [ Tests ] Test updated, passed [ Risks ] Low risk, the non-test part of the patch is trivial [ Checklist ] [X] *all* changes are documented in the d/changelog [X] I reviewed all changes and I approve them [X] attach debdiff against the package in (old)stable [X] the issue is verified as fixed in unstable [ Changes ] Update URL split to fix user and password values if any Cheers, Yadd
diff --git a/debian/changelog b/debian/changelog index 842b4ff..c261d0e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +node-url-parse (1.5.3-1+deb11u2) bullseye; urgency=medium + + * Team upload + * Correctly handle userinfo containing the at sign (Closes: CVE-2022-0512) + + -- Yadd <y...@debian.org> Wed, 31 May 2023 14:43:23 +0400 + node-url-parse (1.5.3-1+deb11u1) bullseye; urgency=medium * Team upload diff --git a/debian/patches/CVE-2022-0512.patch b/debian/patches/CVE-2022-0512.patch new file mode 100644 index 0000000..9b3caed --- /dev/null +++ b/debian/patches/CVE-2022-0512.patch @@ -0,0 +1,135 @@ +Description: Correctly handle userinfo containing the at sign +Author: Luigi Pinca <luigipi...@gmail.com> +Origin: upstream, https://github.com/unshiftio/url-parse/commit/9be7ee88 +Bug: https://huntr.dev/bounties/6d1bc51f-1876-4f5b-a2c2-734e09e8e05b +Forwarded: not-needed +Applied-Upstream: 1.5.6, commit:9be7ee88 +Reviewed-By: Yadd <y...@debian.org> +Last-Update: 2023-05-31 + +--- a/index.js ++++ b/index.js +@@ -306,7 +306,11 @@ + if (parse !== parse) { + url[key] = address; + } else if ('string' === typeof parse) { +- if (~(index = address.indexOf(parse))) { ++ index = parse === '@' ++ ? address.lastIndexOf(parse) ++ : address.indexOf(parse); ++ ++ if (~index) { + if ('number' === typeof instruction[2]) { + url[key] = address.slice(0, index); + address = address.slice(index + instruction[2]); +@@ -373,9 +377,19 @@ + // + url.username = url.password = ''; + if (url.auth) { +- instruction = url.auth.split(':'); +- url.username = instruction[0] || ''; +- url.password = instruction[1] || ''; ++ index = url.auth.indexOf(':'); ++ ++ if (~index) { ++ url.username = url.auth.slice(0, index); ++ url.username = encodeURIComponent(decodeURIComponent(url.username)); ++ ++ url.password = url.auth.slice(index + 1); ++ url.password = encodeURIComponent(decodeURIComponent(url.password)) ++ } else { ++ url.username = encodeURIComponent(decodeURIComponent(url.auth)); ++ } ++ ++ url.auth = url.password ? url.username +':'+ url.password : url.username; + } + + url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host +--- a/test/test.js ++++ b/test/test.js +@@ -712,6 +712,54 @@ + }); + }); + ++ it('handles @ in username', function () { ++ var url = 'http://user@@www.example.com/' ++ , parsed = parse(url); ++ ++ assume(parsed.protocol).equals('http:'); ++ assume(parsed.auth).equals('user%40'); ++ assume(parsed.username).equals('user%40'); ++ assume(parsed.password).equals(''); ++ assume(parsed.hostname).equals('www.example.com'); ++ assume(parsed.pathname).equals('/'); ++ assume(parsed.href).equals('http://user...@www.example.com/'); ++ ++ url = 'http://user...@www.example.com/'; ++ parsed = parse(url); ++ ++ assume(parsed.protocol).equals('http:'); ++ assume(parsed.auth).equals('user%40'); ++ assume(parsed.username).equals('user%40'); ++ assume(parsed.password).equals(''); ++ assume(parsed.hostname).equals('www.example.com'); ++ assume(parsed.pathname).equals('/'); ++ assume(parsed.href).equals('http://user...@www.example.com/'); ++ }); ++ ++ it('handles @ in password', function () { ++ var url = 'http://user@:pas:s@@www.example.com/' ++ , parsed = parse(url); ++ ++ assume(parsed.protocol).equals('http:'); ++ assume(parsed.auth).equals('user%40:pas%3As%40'); ++ assume(parsed.username).equals('user%40'); ++ assume(parsed.password).equals('pas%3As%40'); ++ assume(parsed.hostname).equals('www.example.com'); ++ assume(parsed.pathname).equals('/'); ++ assume(parsed.href).equals('http://user%40:pas%3as...@www.example.com/'); ++ ++ url = 'http://user%40:pas%3as...@www.example.com/' ++ parsed = parse(url); ++ ++ assume(parsed.protocol).equals('http:'); ++ assume(parsed.auth).equals('user%40:pas%3As%40'); ++ assume(parsed.username).equals('user%40'); ++ assume(parsed.password).equals('pas%3As%40'); ++ assume(parsed.hostname).equals('www.example.com'); ++ assume(parsed.pathname).equals('/'); ++ assume(parsed.href).equals('http://user%40:pas%3as...@www.example.com/'); ++ }); ++ + it('accepts multiple ???', function () { + var url = 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s='; + assume(parse(url).query).equals('???&hl=en&src=api&x=2&y=2&z=3&s='); +@@ -1078,6 +1126,30 @@ + + assume(data.username).equals('foo'); + assume(data.href).equals('https://f...@google.com/?foo=bar'); ++ ++ data = parse('https://user@:pass@@example.com/'); ++ assume(data.set('auth', 'user@:pass@')).equals(data); ++ assume(data.username).equals('user%40'); ++ assume(data.password).equals('pass%40'); ++ assume(data.href).equals('https://user%40:pass...@example.com/'); ++ ++ data = parse('https://user%40:pass...@example.com/'); ++ assume(data.set('auth', 'user%40:pass%40')).equals(data); ++ assume(data.username).equals('user%40'); ++ assume(data.password).equals('pass%40'); ++ assume(data.href).equals('https://user%40:pass...@example.com/'); ++ ++ data = parse('https://user:pass:w...@example.com/'); ++ assume(data.set('auth', 'user:pass:word')).equals(data); ++ assume(data.username).equals('user'); ++ assume(data.password).equals('pass%3Aword'); ++ assume(data.href).equals('https://user:pass%3aw...@example.com/'); ++ ++ data = parse('https://user:pass%3aw...@example.com/'); ++ assume(data.set('auth', 'user:pass%3Aword')).equals(data); ++ assume(data.username).equals('user'); ++ assume(data.password).equals('pass%3Aword'); ++ assume(data.href).equals('https://user:pass%3aw...@example.com/'); + }); + + it('lowercases the required values', function () { diff --git a/debian/patches/series b/debian/patches/series index ab0b007..cbd50c3 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ CVE-2022-0686.patch CVE-2022-0691.patch +CVE-2022-0512.patch