Skip to content

Commit

Permalink
Merge pull request #749 from http-party/fix-dos-vuln
Browse files Browse the repository at this point in the history
fix crash on redirect with formfeed in URL
  • Loading branch information
thornjad committed Oct 13, 2021
2 parents a7d08e1 + 2aa7e0e commit df8c736
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
17 changes: 14 additions & 3 deletions lib/core/index.js
Expand Up @@ -31,6 +31,11 @@ function decodePathname(pathname) {
? normalized.replace(/\\/g, '/') : normalized;
}

const nonUrlSafeCharsRgx = /[\x00-\x1F\x20\x7F-\uFFFF]+/g;
function ensureUriEncoded(text) {
return text
return String(text).replace(nonUrlSafeCharsRgx, encodeURIComponent);
}

// Check to see if we should try to compress a file with gzip.
function shouldCompressGzip(req) {
Expand Down Expand Up @@ -161,7 +166,8 @@ module.exports = function createMiddleware(_dir, _options) {
if (opts.weakCompare && clientEtag !== serverEtag
&& clientEtag !== `W/${serverEtag}` && `W/${clientEtag}` !== serverEtag) {
return false;
} else if (!opts.weakCompare && (clientEtag !== serverEtag || clientEtag.indexOf('W/') === 0)) {
}
if (!opts.weakCompare && (clientEtag !== serverEtag || clientEtag.indexOf('W/') === 0)) {
return false;
}
}
Expand Down Expand Up @@ -340,8 +346,10 @@ module.exports = function createMiddleware(_dir, _options) {
}, res, next);
} else {
// Try to serve default ./404.html
const rawUrl = (handleError ? `/${path.join(baseDir, `404.${defaultExt}`)}` : req.url);
const encodedUrl = ensureUriEncoded(rawUrl);
middleware({
url: (handleError ? `/${path.join(baseDir, `404.${defaultExt}`)}` : req.url),
url: encodedUrl,
headers: req.headers,
statusCode: 404,
}, res, next);
Expand All @@ -359,7 +367,10 @@ module.exports = function createMiddleware(_dir, _options) {
if (!pathname.match(/\/$/)) {
res.statusCode = 302;
const q = parsed.query ? `?${parsed.query}` : '';
res.setHeader('location', `${parsed.pathname}/${q}`);
res.setHeader(
'location',
ensureUriEncoded(`${parsed.pathname}/${q}`)
);
res.end();
return;
}
Expand Down
13 changes: 13 additions & 0 deletions test/main.test.js
Expand Up @@ -87,6 +87,19 @@ test('http-server main', (t) => {
.indexOf('X-Test') >= 0, 204);
}).catch(err => t.fail(err.toString())),

t.test(
"Regression: don't crash on control characters in query strings",
{},
(t) => {
requestAsync({
uri: encodeURI('http://localhost:8080/file?\x0cfoo'),
}).then(res => {
t.equal(res.statusCode, 200);
}).catch(err => t.fail(err.toString()))
.finally(() => t.end());
}
),

// Light compression testing. Heavier compression tests exist in
// compression.test.js
requestAsync({
Expand Down

0 comments on commit df8c736

Please sign in to comment.