Skip to content

Commit

Permalink
feat(dispatcher): normalization (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBuchholz committed Feb 4, 2024
1 parent db47641 commit 5c9c2b5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
9 changes: 7 additions & 2 deletions reserve/src/dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,12 @@ function dispatch (context, url, index = 0) {
module.exports = function (configuration, request, response) {
let { url } = request
if (url.indexOf('.') !== -1 || url.indexOf('%') !== -1) {
const { pathname, search, hash } = new URL(url, 'p:/')
url = decodeURIComponent(pathname) + search + hash
try {
const { pathname, search, hash } = new URL(url, 'p:/')
url = decodeURIComponent(pathname.replace(/%0\d|%1\d/g, '')) + search + hash
} catch (e) {
url = 400
}
}

const {
Expand All @@ -152,6 +156,7 @@ module.exports = function (configuration, request, response) {
id,
internal: !!request[$requestInternal],
method: request.method,
incomingUrl: request.url,
url,
headers: { ...request.headers },
start: new Date(),
Expand Down
26 changes: 25 additions & 1 deletion reserve/src/dispatcher.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ describe('dispatcher', () => {
})
})

describe.only('URL normalization for security', () => {
describe('URL normalization for security', () => {
it('avoids path traversal by normalizing the URL if needed (using root ../)', () => {
const request = new Request('GET')
request.setForgedUrl('/../file.txt')
Expand Down Expand Up @@ -553,5 +553,29 @@ describe('dispatcher', () => {
assert.strictEqual(response.toString(), 'Hello World!')
})
})

for (let i = 1; i < 32; ++i) {
it('works around forbidden chars', () => {
const request = new Request('GET')
request.setForgedUrl(`/test/%2E%2E/file%${Number(i).toString(8).padStart(2, '0')}.txt`)
return dispatch({ request })
.then(({ emitted, response }) => {
assert.ok(!hasError(emitted))
assert.strictEqual(response.statusCode, 200)
assert.strictEqual(response.headers['Content-Type'], textMimeType)
assert.strictEqual(response.toString(), 'Hello World!')
})
})
}

it('rejects malformed URLs', () => {
const request = new Request('GET')
request.setForgedUrl('/test/%2E%2E/file%0.txt')
return dispatch({ request })
.then(({ emitted, response }) => {
assert.ok(!hasError(emitted))
assert.strictEqual(response.statusCode, 400)
})
})
})
})

0 comments on commit 5c9c2b5

Please sign in to comment.