Skip to content

Commit 6497d99

Browse files
committed
fix(nuxt): reject cross-origin paths in reloadNuxtApp
(cherry picked from commit d97358675c1239d553155fbdf0f084c12daf7f0e) Refs: GHSA-c9cv-mq2m-ppp3
1 parent 1f2dd5e commit 6497d99

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

packages/nuxt/src/app/composables/chunk.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface ReloadNuxtAppOptions {
2222
* The path to reload. If this is different from the current window location it will
2323
* trigger a navigation and add an entry in the browser history.
2424
*
25-
* URLs with script-like protocols (e.g. `javascript:`, `data:`) are rejected.
25+
* Cross-origin paths and URLs with script-like protocols (e.g. `javascript:`, `data:`) are rejected.
2626
* @default {window.location.pathname}
2727
*/
2828
path?: string
@@ -33,9 +33,12 @@ export function reloadNuxtApp (options: ReloadNuxtAppOptions = {}) {
3333
if (import.meta.server) { return }
3434
const path = options.path || window.location.pathname
3535

36-
const { protocol } = new URL(path, window.location.href)
37-
if (protocol && isScriptProtocol(protocol)) {
38-
throw new Error(`Cannot navigate to a URL with '${protocol}' protocol.`)
36+
const url = new URL(path, window.location.href)
37+
if (url.host !== window.location.host) {
38+
throw new Error(`Cannot navigate to a URL with a different host: '${path}'.`)
39+
}
40+
if (url.protocol && isScriptProtocol(url.protocol)) {
41+
throw new Error(`Cannot navigate to a URL with '${url.protocol}' protocol.`)
3942
}
4043

4144
let handledPath: Record<string, any> = {}

test/nuxt/composables.test.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -563,14 +563,27 @@ describe('routing utilities: `navigateTo`', () => {
563563
})
564564
it('reloadNuxtApp should disallow paths with data/script URLs', () => {
565565
const urls = [
566-
['javascript:alert("hi")', 'javascript'],
567-
['data:alert("hi")', 'data'],
568-
['\0data:alert("hi")', 'data'],
566+
'javascript:alert("hi")',
567+
'data:alert("hi")',
568+
'\0data:alert("hi")',
569569
]
570-
for (const [url, protocol] of urls) {
571-
expect(() => reloadNuxtApp({ path: url })).toThrow(`Cannot navigate to a URL with '${protocol}:' protocol.`)
570+
for (const url of urls) {
571+
expect(() => reloadNuxtApp({ path: url })).toThrow(`Cannot navigate to a URL with a different host: '${url}'.`)
572+
}
573+
})
574+
it('reloadNuxtApp should disallow cross-origin paths', () => {
575+
const urls = [
576+
'//evil.com',
577+
'https://evil.com',
578+
'\\\\evil.com',
579+
]
580+
for (const url of urls) {
581+
expect(() => reloadNuxtApp({ path: url })).toThrow(`Cannot navigate to a URL with a different host: '${url}'.`)
572582
}
573583
})
584+
it('reloadNuxtApp should allow same-origin paths', () => {
585+
expect(() => reloadNuxtApp({ path: '/legit/path' })).not.toThrow()
586+
})
574587
it('navigateTo should replace current navigation state if called within middleware', () => {
575588
const nuxtApp = useNuxtApp()
576589
nuxtApp._processingMiddleware = true

0 commit comments

Comments
 (0)