Skip to content

Commit a5eb171

Browse files
committed
Fleshing out tests futher
1 parent 9feb734 commit a5eb171

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

src/lib/utils.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ describe('sanitizeUrl', () => {
4646
})
4747
})
4848

49+
describe('should reject malicious hosts', () => {
50+
const invalidProtocolUrls = [
51+
'https://www.$(calc.exe).com/foo',
52+
'https://www.example.com:$(calc.exe)/foo',
53+
]
54+
55+
invalidProtocolUrls.forEach((url) => {
56+
it(`should reject: ${url}`, () => {
57+
expect(() => sanitizeUrl(url)).toThrow('Invalid url to pass to open()')
58+
})
59+
})
60+
})
61+
4962
describe('should properly encode URL components', () => {
5063
it('should reject URLs with spaces in hostname', () => {
5164
// URLs with spaces in hostname are invalid

src/lib/utils.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,11 +706,22 @@ export function getServerUrlHash(serverUrl: string): string {
706706
}
707707

708708
export function sanitizeUrl(raw: string) {
709-
const url = new URL(raw)
710-
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
711-
throw new Error(`Invalid url to pass to open(): ${url}`)
709+
const abort = () => {
710+
throw new Error(`Invalid url to pass to open(): ${raw}`)
712711
}
713-
url.hostname = encodeURIComponent(url.hostname)
712+
let url!: URL
713+
try {
714+
url = new URL(raw)
715+
} catch (_) {
716+
abort()
717+
}
718+
719+
// Don't allow any other scheme than http(s)
720+
if (url.protocol !== 'https:' && url.protocol !== 'http:') abort()
721+
// Hostnames can't be updated, but let's reject if they contain anything suspicious
722+
if (url.hostname !== encodeURIComponent(url.hostname)) abort()
723+
724+
// Forcibly sanitise all the pieces of the URL
714725
url.pathname = url.pathname.slice(0, 1) + encodeURIComponent(url.pathname.slice(1)).replace(/%2f/ig,'/')
715726
url.search = url.search.slice(0, 1) + Array.from(url.searchParams.entries()).map(sanitizeParam).join('&')
716727
url.hash = url.hash.slice(0, 1) + encodeURIComponent(url.hash.slice(1))

0 commit comments

Comments
 (0)