diff options
| author | Amir Naseredini <amir.naseredini@canonical.com> | 2023-05-25 11:27:36 +0100 |
|---|---|---|
| committer | git-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com> | 2023-05-30 09:11:05 +0000 |
| commit | 239627af15739e292156a057d7415556f9d5a40e (patch) | |
| tree | 161e4ac39f3d71b8c0e70199d702276cca0916c5 | |
| parent | 4391d38b75b5fd53fbdec331d4be1f50d813f0b8 (diff) | |
| parent | b932131875190c09bb69783784a696f3e351bd69 (diff) | |
6.0.1+dfsg-1+deb10u1build0.18.04.1 (patches applied)applied/6.0.1+dfsg-1+deb10u1build0.18.04.1applied/ubuntu/bionic-updatesapplied/ubuntu/bionic-securityapplied/ubuntu/bionic-devel
Imported using git-ubuntu import.
| -rw-r--r-- | debian/.gitlab-ci.yml | 8 | ||||
| -rw-r--r-- | debian/changelog | 16 | ||||
| -rw-r--r-- | debian/control | 1 | ||||
| -rw-r--r-- | debian/patches/CVE-2022-29167.patch | 117 | ||||
| -rw-r--r-- | debian/patches/series | 1 | ||||
| -rwxr-xr-x | lib/utils.js | 22 | ||||
| -rwxr-xr-x | test/server.js | 14 | ||||
| -rwxr-xr-x | test/utils.js | 6 |
8 files changed, 172 insertions, 13 deletions
diff --git a/debian/.gitlab-ci.yml b/debian/.gitlab-ci.yml new file mode 100644 index 0000000..d61df30 --- /dev/null +++ b/debian/.gitlab-ci.yml @@ -0,0 +1,8 @@ +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml + +variables: + RELEASE: 'buster' + SALSA_CI_COMPONENTS: 'main contrib non-free' + SALSA_CI_DISABLE_REPROTEST: 1 + SALSA_CI_DISABLE_LINTIAN: 1
\ No newline at end of file diff --git a/debian/changelog b/debian/changelog index 19e1d68..19facbb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +node-hawk (6.0.1+dfsg-1+deb10u1build0.18.04.1) bionic-security; urgency=medium + + * fake sync from Debian + + -- Amir Naseredini <amir.naseredini@canonical.com> Thu, 25 May 2023 11:27:36 +0100 + +node-hawk (6.0.1+dfsg-1+deb10u1) buster-security; urgency=high + + * CVE-2022-29167: Prevent an issue where Hawk used a regular expression to + parse `Host` HTTP headers which was subject to regular expression DoS + attack. Each added character in the attacker's input increased the + computation time exponentially. + * Add new runtime dependency on node-url to satisfy patch for CVE-2022-29167. + + -- Chris Lamb <lamby@debian.org> Fri, 23 Dec 2022 06:18:20 +0000 + node-hawk (6.0.1+dfsg-1) unstable; urgency=low * Initial release (Closes: #861795) diff --git a/debian/control b/debian/control index 9ae906a..7a129ef 100644 --- a/debian/control +++ b/debian/control @@ -21,6 +21,7 @@ Depends: , node-hoek (>= 4.0.0) , node-boom (>= 4.0.0) , node-cryptiles (>= 3.0.0) + , node-url Description: HTTP Hawk Authentication Scheme Hawk is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial HTTP request cryptographic verification. diff --git a/debian/patches/CVE-2022-29167.patch b/debian/patches/CVE-2022-29167.patch new file mode 100644 index 0000000..d4eb214 --- /dev/null +++ b/debian/patches/CVE-2022-29167.patch @@ -0,0 +1,117 @@ +From: Yaraslau Kurmyza <yarik@mozilla.com> +Date: Mon, 2 May 2022 13:47:12 +0200 +Subject: [PATCH] Parse URLs using stdlib + +--- + lib/utils.js | 22 ++++++++++++---------- + test/server.js | 14 ++++++++++++++ + test/utils.js | 6 +++--- + 3 files changed, 29 insertions(+), 13 deletions(-) + +diff --git a/lib/utils.js b/lib/utils.js +index ecb64d3..46c5a1b 100755 +--- a/lib/utils.js ++++ b/lib/utils.js +@@ -4,6 +4,7 @@ + + const Sntp = require('sntp'); + const Boom = require('boom'); ++const Url = require('url'); + + + // Declare internals +@@ -22,12 +23,6 @@ exports.limits = { + }; + + +-// Extract host and port from request +- +-// $1 $2 +-internals.hostHeaderRegex = /^(?:(?:\r\n)?\s)*((?:[^:]+)|(?:\[[^\]]+\]))(?::(\d+))?(?:(?:\r\n)?\s)*$/; // (IPv4, hostname)|(IPv6) +- +- + exports.parseHost = function (req, hostHeaderName) { + + hostHeaderName = (hostHeaderName ? hostHeaderName.toLowerCase() : 'host'); +@@ -40,14 +35,21 @@ exports.parseHost = function (req, hostHeaderName) { + return null; + } + +- const hostParts = hostHeader.match(internals.hostHeaderRegex); +- if (!hostParts) { ++ if (hostHeader.indexOf('/') !== -1) { ++ return null; ++ } ++ ++ let uri; ++ try { ++ uri = new Url.URL('http://' + hostHeader); ++ } ++ catch (err) { + return null; + } + + return { +- name: hostParts[1], +- port: (hostParts[2] ? hostParts[2] : (req.connection && req.connection.encrypted ? 443 : 80)) ++ name: uri.hostname, ++ port: (uri.port ? uri.port : (req.connection && req.connection.encrypted ? 443 : 80)) + }; + }; + +diff --git a/test/server.js b/test/server.js +index 3638f02..77853c8 100755 +--- a/test/server.js ++++ b/test/server.js +@@ -551,6 +551,20 @@ describe('Server', () => { + }); + }); + ++ it('errors on an bad host header (includes path and query)', async () => { ++ ++ const req = { ++ method: 'GET', ++ url: '/resource/4?filter=a', ++ headers: { ++ host: 'example.com:8080/path?x=z', ++ authorization: 'Hawk' ++ } ++ }; ++ ++ await expect(Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() })).to.reject('Invalid Host header'); ++ }); ++ + it('errors on an bad host header (pad port)', (done) => { + + const req = { +diff --git a/test/utils.js b/test/utils.js +index d7a265c..c8c7931 100755 +--- a/test/utils.js ++++ b/test/utils.js +@@ -64,7 +64,7 @@ describe('Utils', () => { + method: 'POST', + url: '/resource/4?filter=a', + headers: { +- host: '[123:123:123]', ++ host: '[123:123::123]', + 'content-type': 'text/plain;x=y' + }, + connection: { +@@ -82,7 +82,7 @@ describe('Utils', () => { + method: 'POST', + url: '/resource/4?filter=a', + headers: { +- host: '[123:123:123]:8000', ++ host: '[123:123::123]:8000', + 'content-type': 'text/plain;x=y' + }, + connection: { +@@ -92,7 +92,7 @@ describe('Utils', () => { + + const host = Hawk.utils.parseHost(req, 'Host'); + expect(host.port).to.equal('8000'); +- expect(host.name).to.equal('[123:123:123]'); ++ expect(host.name).to.equal('[123:123::123]'); + done(); + }); + diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..43fa212 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +CVE-2022-29167.patch diff --git a/lib/utils.js b/lib/utils.js index ecb64d3..46c5a1b 100755 --- a/lib/utils.js +++ b/lib/utils.js @@ -4,6 +4,7 @@ const Sntp = require('sntp'); const Boom = require('boom'); +const Url = require('url'); // Declare internals @@ -22,12 +23,6 @@ exports.limits = { }; -// Extract host and port from request - -// $1 $2 -internals.hostHeaderRegex = /^(?:(?:\r\n)?\s)*((?:[^:]+)|(?:\[[^\]]+\]))(?::(\d+))?(?:(?:\r\n)?\s)*$/; // (IPv4, hostname)|(IPv6) - - exports.parseHost = function (req, hostHeaderName) { hostHeaderName = (hostHeaderName ? hostHeaderName.toLowerCase() : 'host'); @@ -40,14 +35,21 @@ exports.parseHost = function (req, hostHeaderName) { return null; } - const hostParts = hostHeader.match(internals.hostHeaderRegex); - if (!hostParts) { + if (hostHeader.indexOf('/') !== -1) { + return null; + } + + let uri; + try { + uri = new Url.URL('http://' + hostHeader); + } + catch (err) { return null; } return { - name: hostParts[1], - port: (hostParts[2] ? hostParts[2] : (req.connection && req.connection.encrypted ? 443 : 80)) + name: uri.hostname, + port: (uri.port ? uri.port : (req.connection && req.connection.encrypted ? 443 : 80)) }; }; diff --git a/test/server.js b/test/server.js index 3638f02..77853c8 100755 --- a/test/server.js +++ b/test/server.js @@ -551,6 +551,20 @@ describe('Server', () => { }); }); + it('errors on an bad host header (includes path and query)', async () => { + + const req = { + method: 'GET', + url: '/resource/4?filter=a', + headers: { + host: 'example.com:8080/path?x=z', + authorization: 'Hawk' + } + }; + + await expect(Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() })).to.reject('Invalid Host header'); + }); + it('errors on an bad host header (pad port)', (done) => { const req = { diff --git a/test/utils.js b/test/utils.js index d7a265c..c8c7931 100755 --- a/test/utils.js +++ b/test/utils.js @@ -64,7 +64,7 @@ describe('Utils', () => { method: 'POST', url: '/resource/4?filter=a', headers: { - host: '[123:123:123]', + host: '[123:123::123]', 'content-type': 'text/plain;x=y' }, connection: { @@ -82,7 +82,7 @@ describe('Utils', () => { method: 'POST', url: '/resource/4?filter=a', headers: { - host: '[123:123:123]:8000', + host: '[123:123::123]:8000', 'content-type': 'text/plain;x=y' }, connection: { @@ -92,7 +92,7 @@ describe('Utils', () => { const host = Hawk.utils.parseHost(req, 'Host'); expect(host.port).to.equal('8000'); - expect(host.name).to.equal('[123:123:123]'); + expect(host.name).to.equal('[123:123::123]'); done(); }); |
