summaryrefslogtreecommitdiff
diff options
authorAmir Naseredini <amir.naseredini@canonical.com>2023-05-25 11:27:36 +0100
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2023-05-30 09:11:05 +0000
commit239627af15739e292156a057d7415556f9d5a40e (patch)
tree161e4ac39f3d71b8c0e70199d702276cca0916c5
parent4391d38b75b5fd53fbdec331d4be1f50d813f0b8 (diff)
parentb932131875190c09bb69783784a696f3e351bd69 (diff)
Imported using git-ubuntu import.
-rw-r--r--debian/.gitlab-ci.yml8
-rw-r--r--debian/changelog16
-rw-r--r--debian/control1
-rw-r--r--debian/patches/CVE-2022-29167.patch117
-rw-r--r--debian/patches/series1
-rwxr-xr-xlib/utils.js22
-rwxr-xr-xtest/server.js14
-rwxr-xr-xtest/utils.js6
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();
});