Skip to content
This repository was archived by the owner on Feb 2, 2024. It is now read-only.

Commit f90f26d

Browse files
authored
Merge pull request #44 from fastify/fixing-sec-issue-buildurl
Sanitising URL instance parameters
2 parents de2126d + c2b8467 commit f90f26d

File tree

3 files changed

+66
-5
lines changed

3 files changed

+66
-5
lines changed

index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use strict'
22

3-
const URL = require('url').URL
43
const pump = require('pump')
54
const lru = require('tiny-lru')
65
const querystring = require('querystring')
@@ -10,7 +9,8 @@ const {
109
filterPseudoHeaders,
1110
copyHeaders,
1211
stripHttp1ConnectionHeaders,
13-
filterHeaders
12+
filterHeaders,
13+
buildURL
1414
} = require('./lib/utils')
1515

1616
function populateHeaders (headers, body, contentType) {
@@ -170,11 +170,11 @@ function getReqUrl (source, cache, base, opts) {
170170
const cacheKey = reqBase + source
171171
url = cache.get(cacheKey)
172172
if (!url) {
173-
url = new URL(source, reqBase)
173+
url = buildURL(source, reqBase)
174174
cache.set(cacheKey, url)
175175
}
176176
} else {
177-
url = new URL(source, reqBase)
177+
url = buildURL(source, reqBase)
178178
}
179179

180180
return url

lib/utils.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,17 @@ function filterHeaders (headers, filter) {
7070
return dest
7171
}
7272

73+
function buildURL (source = '', reqBase) {
74+
// issue ref: https://github.com/fastify/fast-proxy/issues/42
75+
const cleanSource = source.replace(/\/+/g, '/')
76+
77+
return new URL(cleanSource, reqBase)
78+
}
79+
7380
module.exports = {
7481
copyHeaders,
7582
stripHttp1ConnectionHeaders,
7683
filterPseudoHeaders,
77-
filterHeaders
84+
filterHeaders,
85+
buildURL
7886
}

test/10.build-url.test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* global describe, it */
2+
'use strict'
3+
4+
const expect = require('chai').expect
5+
const { buildURL } = require('./../lib/utils')
6+
7+
describe('buildURL', () => {
8+
it('should produce invalid URL - //10.0.0.10/', function () {
9+
const url = new URL('//10.0.0.10/', 'http://localhost')
10+
expect(url.origin).to.equal('http://10.0.0.10')
11+
expect(url.pathname).to.equal('/')
12+
expect(url.href).to.equal('http://10.0.0.10/')
13+
})
14+
15+
it('should produce invalid URL - //httpbin.org/hi', function () {
16+
const url = new URL('//httpbin.org/hi', 'http://localhost')
17+
expect(url.origin).to.equal('http://httpbin.org')
18+
expect(url.pathname).to.equal('/hi')
19+
expect(url.href).to.equal('http://httpbin.org/hi')
20+
})
21+
22+
it('should produce valid URL (2 params)', function () {
23+
const url = buildURL('/hi', 'http://localhost')
24+
25+
expect(url.origin).to.equal('http://localhost')
26+
expect(url.pathname).to.equal('/hi')
27+
expect(url.href).to.equal('http://localhost/hi')
28+
})
29+
30+
it('should produce valid URL (1 param)', function () {
31+
const url = buildURL('http://localhost/hi')
32+
33+
expect(url.origin).to.equal('http://localhost')
34+
expect(url.pathname).to.equal('/hi')
35+
expect(url.href).to.equal('http://localhost/hi')
36+
})
37+
38+
it('should sanitize invalid source (2 params) - //10.0.0.10/hi', function () {
39+
const url = buildURL('//10.0.0.10/hi', 'http://localhost')
40+
41+
expect(url.origin).to.equal('http://localhost')
42+
expect(url.pathname).to.equal('/10.0.0.10/hi')
43+
expect(url.href).to.equal('http://localhost/10.0.0.10/hi')
44+
})
45+
46+
it('should sanitize invalid source (2 params) - //httpbin.org/hi', function () {
47+
const url = buildURL('//httpbin.org/hi', 'http://localhost')
48+
49+
expect(url.origin).to.equal('http://localhost')
50+
expect(url.pathname).to.equal('/httpbin.org/hi')
51+
expect(url.href).to.equal('http://localhost/httpbin.org/hi')
52+
})
53+
})

0 commit comments

Comments
 (0)