From 7dfc90cb8cd2918c775f847791dad2b21b4d5ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Mon, 24 Mar 2025 18:25:11 +0900 Subject: [PATCH] fix: fs raw query with query separators (#19702) --- .../src/node/server/middlewares/transform.ts | 15 +++++++- .../fs-serve/__tests__/fs-serve.spec.ts | 14 +++++++ playground/fs-serve/root/src/index.html | 38 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index 4bc1042c636084..861c1b360d7aa1 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -44,6 +44,7 @@ import { ensureServingAccess } from './static' const debugCache = createDebugger('vite:cache') const knownIgnoreList = new Set(['/', '/favicon.ico']) +const trailingQuerySeparatorsRE = /[?&]+$/ export function transformMiddleware( server: ViteDevServer, @@ -167,9 +168,19 @@ export function transformMiddleware( } } + const urlWithoutTrailingQuerySeparators = url.replace( + trailingQuerySeparatorsRE, + '', + ) if ( - (rawRE.test(url) || urlRE.test(url)) && - !ensureServingAccess(url, server, res, next) + (rawRE.test(urlWithoutTrailingQuerySeparators) || + urlRE.test(urlWithoutTrailingQuerySeparators)) && + !ensureServingAccess( + urlWithoutTrailingQuerySeparators, + server, + res, + next, + ) ) { return } diff --git a/playground/fs-serve/__tests__/fs-serve.spec.ts b/playground/fs-serve/__tests__/fs-serve.spec.ts index 49d2b5bf1753e2..ae5fde51937431 100644 --- a/playground/fs-serve/__tests__/fs-serve.spec.ts +++ b/playground/fs-serve/__tests__/fs-serve.spec.ts @@ -96,6 +96,20 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.unsafe-fs-fetch-raw-status')).toBe('403') }) + test('unsafe fs fetch query 1', async () => { + expect(await page.textContent('.unsafe-fs-fetch-raw-query1')).toBe('') + expect(await page.textContent('.unsafe-fs-fetch-raw-query1-status')).toBe( + '403', + ) + }) + + test('unsafe fs fetch query 2', async () => { + expect(await page.textContent('.unsafe-fs-fetch-raw-query2')).toBe('') + expect(await page.textContent('.unsafe-fs-fetch-raw-query2-status')).toBe( + '403', + ) + }) + test('unsafe fs fetch with special characters (#8498)', async () => { expect(await page.textContent('.unsafe-fs-fetch-8498')).toBe('') expect(await page.textContent('.unsafe-fs-fetch-8498-status')).toBe('404') diff --git a/playground/fs-serve/root/src/index.html b/playground/fs-serve/root/src/index.html index 9f56c8831c12d9..314f9e985b6e35 100644 --- a/playground/fs-serve/root/src/index.html +++ b/playground/fs-serve/root/src/index.html @@ -37,6 +37,10 @@

Unsafe /@fs/ Fetch


 

 

+

+

+

+

 

 

 

@@ -209,6 +213,40 @@ 

Denied

console.error(e) }) + fetch( + joinUrlSegments( + base, + joinUrlSegments('/@fs/', ROOT) + '/unsafe.json?import&raw??', + ), + ) + .then((r) => { + text('.unsafe-fs-fetch-raw-query1-status', r.status) + return r.json() + }) + .then((data) => { + text('.unsafe-fs-fetch-raw-query1', JSON.stringify(data)) + }) + .catch((e) => { + console.error(e) + }) + + fetch( + joinUrlSegments( + base, + joinUrlSegments('/@fs/', ROOT) + '/unsafe.json?import&raw?&', + ), + ) + .then((r) => { + text('.unsafe-fs-fetch-raw-query2-status', r.status) + return r.json() + }) + .then((data) => { + text('.unsafe-fs-fetch-raw-query2', JSON.stringify(data)) + }) + .catch((e) => { + console.error(e) + }) + // outside root with special characters #8498 fetch( joinUrlSegments(