From dd9b9a9b23e3896403c90a740e7f1f0892feb402 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Sun, 21 Jan 2024 16:54:03 +0900 Subject: [PATCH] fix(request): handle "double dots" in URL (#124) --- src/request.ts | 9 ++++++++- test/assets/secret.txt | 1 + test/request.test.ts | 13 +++++++++++++ test/serve-static.test.ts | 5 +++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/assets/secret.txt diff --git a/src/request.ts b/src/request.ts index a341847..7fa4308 100644 --- a/src/request.ts +++ b/src/request.ts @@ -3,6 +3,7 @@ import type { IncomingMessage } from 'node:http' import type { Http2ServerRequest } from 'node:http2' +import { resolve } from 'node:path' import { Readable } from 'node:stream' const newRequestFromIncoming = ( @@ -41,7 +42,13 @@ const requestPrototype: Record = { }, get url() { - return `http://${this[incomingKey].headers.host}${this[incomingKey].url}` + let path = this[incomingKey]['path'] + if (!path) { + const originalPath = this[incomingKey].url + path = /\.\./.test(originalPath) ? resolve(originalPath) : originalPath + this[incomingKey]['path'] = path + } + return `http://${this[incomingKey].headers.host}${path}` }, [getRequestCache]() { diff --git a/test/assets/secret.txt b/test/assets/secret.txt new file mode 100644 index 0000000..536aca3 --- /dev/null +++ b/test/assets/secret.txt @@ -0,0 +1 @@ +secret \ No newline at end of file diff --git a/test/request.test.ts b/test/request.test.ts index 756f2d8..4444c9c 100644 --- a/test/request.test.ts +++ b/test/request.test.ts @@ -17,4 +17,17 @@ describe('Request', () => { expect(req.url).toBe('http://localhost/') expect(req.headers.get('host')).toBe('localhost') }) + + it('Should resolve double dots in URL', async () => { + const req = newRequest({ + headers: { + host: 'localhost', + }, + url: '/static/../foo.txt', + } as IncomingMessage) + expect(req).toBeInstanceOf(global.Request) + expect(req.url).toBe('http://localhost/foo.txt') + // Check if cached value is returned correctly + expect(req.url).toBe('http://localhost/foo.txt') + }) }) diff --git a/test/serve-static.test.ts b/test/serve-static.test.ts index b8af601..b26a6e8 100644 --- a/test/serve-static.test.ts +++ b/test/serve-static.test.ts @@ -129,4 +129,9 @@ describe('Serve Static Middleware', () => { './not-found/on-not-found/foo.txt is not found, request to /on-not-found/foo.txt' ) }) + + it('Should handle double dots in URL', async () => { + const res = await request(server).get('/static/../secret.txt') + expect(res.status).toBe(404) + }) })