Skip to content

Commit 4f6b49b

Browse files
fix: x-forwarded-proto header parsing (#392)
Some reverse proxies put multiple protocols into x-forwarded-proto which caused the `new URL()` constructor to fail. I removed the parsed protocol from the URL constructor, since we're only using that with a static hostname anyway. Then in the instance where we do need the parsed protocol, I added some logic to capture the first protocol if there's more than one. Fixes: #378
1 parent d6ee495 commit 4f6b49b

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

packages/node/__tests__/lib/process-request.test.ts

+7
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,13 @@ test('#url protocol x-forwarded-proto', () =>
402402
// This regex is for supertest's random port numbers
403403
.expect(({ body }) => expect(body.url).toMatch(/^https/)));
404404

405+
test('#url protocol x-forwarded-proto multiple', () =>
406+
request(createApp())
407+
.post('/')
408+
.set('x-forwarded-proto', 'https,http')
409+
// This regex is for supertest's random port numbers
410+
.expect(({ body }) => expect(body.url).toMatch(/^https:\/\/127.0.0.1/)));
411+
405412
test('#url-basepath', () =>
406413
request(createApp())
407414
.post('/test-base-path/a')

packages/node/src/lib/process-request.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,15 @@ export default function processRequest(
178178
const host = fixHeader(req.headers['x-forwarded-host']) || req.headers.host;
179179
// We use a fake host here because we rely on the host header which could be redacted.
180180
// We only ever use this reqUrl with the fake hostname for the pathname and querystring.
181-
const reqUrl = new URL(req.url, `${protocol}://readme.io`);
181+
const reqUrl = new URL(req.url, `https://readme.io`);
182182

183183
const requestData = {
184184
method: req.method,
185185
url: url.format({
186-
protocol,
186+
// Handle cases where some reverse proxies put two protocols into x-forwarded-proto
187+
// This line does the following: "https,http" -> "https"
188+
// https://github.com/readmeio/metrics-sdks/issues/378
189+
protocol: protocol.split(',')[0],
187190
host,
188191
pathname: reqUrl.pathname,
189192
// Search includes the leading questionmark, format assumes there isn't one, so we trim that off.

0 commit comments

Comments
 (0)