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 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 000..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
+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
+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');
++