Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

Commit

Permalink
Merge pull request #286 from lotas/regex-exploit-fix
Browse files Browse the repository at this point in the history
Parse URLs using stdlib
  • Loading branch information
matt-boris authored May 3, 2022
2 parents aa5e09e + ade1341 commit d10d72c
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 13 deletions.
22 changes: 12 additions & 10 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const Boom = require('@hapi/boom');
const Url = require('url');


const internals = {};
Expand All @@ -17,12 +18,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');
Expand All @@ -35,14 +30,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))
};
};

Expand Down
14 changes: 14 additions & 0 deletions test/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,20 @@ describe('Server', () => {
await expect(Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() })).to.reject('Invalid Host header');
});

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)', async () => {

const req = {
Expand Down
6 changes: 3 additions & 3 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,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: {
Expand All @@ -72,7 +72,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: {
Expand All @@ -82,7 +82,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]');
});

it('errors on header too long', () => {
Expand Down

0 comments on commit d10d72c

Please sign in to comment.