Skip to content

Commit 807d7f0

Browse files
authored
fix: backport #19702, fs raw query with query separators (#19703)
1 parent 3ccbdbe commit 807d7f0

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

packages/vite/src/node/server/middlewares/transform.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { ensureServingAccess } from './static'
4141
const debugCache = createDebugger('vite:cache')
4242

4343
const knownIgnoreList = new Set(['/', '/favicon.ico'])
44+
const trailingQuerySeparatorsRE = /[?&]+$/
4445

4546
/**
4647
* A middleware that short-circuits the middleware chain to serve cached transformed modules
@@ -163,9 +164,19 @@ export function transformMiddleware(
163164
warnAboutExplicitPublicPathInUrl(url)
164165
}
165166

167+
const urlWithoutTrailingQuerySeparators = url.replace(
168+
trailingQuerySeparatorsRE,
169+
'',
170+
)
166171
if (
167-
(rawRE.test(url) || urlRE.test(url)) &&
168-
!ensureServingAccess(url, server, res, next)
172+
(rawRE.test(urlWithoutTrailingQuerySeparators) ||
173+
urlRE.test(urlWithoutTrailingQuerySeparators)) &&
174+
!ensureServingAccess(
175+
urlWithoutTrailingQuerySeparators,
176+
server,
177+
res,
178+
next,
179+
)
169180
) {
170181
return
171182
}

playground/fs-serve/__tests__/fs-serve.spec.ts

+14
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ describe.runIf(isServe)('main', () => {
9696
expect(await page.textContent('.unsafe-fs-fetch-raw-status')).toBe('403')
9797
})
9898

99+
test('unsafe fs fetch query 1', async () => {
100+
expect(await page.textContent('.unsafe-fs-fetch-raw-query1')).toBe('')
101+
expect(await page.textContent('.unsafe-fs-fetch-raw-query1-status')).toBe(
102+
'403',
103+
)
104+
})
105+
106+
test('unsafe fs fetch query 2', async () => {
107+
expect(await page.textContent('.unsafe-fs-fetch-raw-query2')).toBe('')
108+
expect(await page.textContent('.unsafe-fs-fetch-raw-query2-status')).toBe(
109+
'403',
110+
)
111+
})
112+
99113
test('unsafe fs fetch with special characters (#8498)', async () => {
100114
expect(await page.textContent('.unsafe-fs-fetch-8498')).toBe('')
101115
expect(await page.textContent('.unsafe-fs-fetch-8498-status')).toBe('404')

playground/fs-serve/root/src/index.html

+38
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ <h2>Unsafe /@fs/ Fetch</h2>
3737
<pre class="unsafe-fs-fetch"></pre>
3838
<pre class="unsafe-fs-fetch-raw-status"></pre>
3939
<pre class="unsafe-fs-fetch-raw"></pre>
40+
<pre class="unsafe-fs-fetch-raw-query1-status"></pre>
41+
<pre class="unsafe-fs-fetch-raw-query1"></pre>
42+
<pre class="unsafe-fs-fetch-raw-query2-status"></pre>
43+
<pre class="unsafe-fs-fetch-raw-query2"></pre>
4044
<pre class="unsafe-fs-fetch-8498-status"></pre>
4145
<pre class="unsafe-fs-fetch-8498"></pre>
4246
<pre class="unsafe-fs-fetch-8498-2-status"></pre>
@@ -209,6 +213,40 @@ <h2>Denied</h2>
209213
console.error(e)
210214
})
211215

216+
fetch(
217+
joinUrlSegments(
218+
base,
219+
joinUrlSegments('/@fs/', ROOT) + '/unsafe.json?import&raw??',
220+
),
221+
)
222+
.then((r) => {
223+
text('.unsafe-fs-fetch-raw-query1-status', r.status)
224+
return r.json()
225+
})
226+
.then((data) => {
227+
text('.unsafe-fs-fetch-raw-query1', JSON.stringify(data))
228+
})
229+
.catch((e) => {
230+
console.error(e)
231+
})
232+
233+
fetch(
234+
joinUrlSegments(
235+
base,
236+
joinUrlSegments('/@fs/', ROOT) + '/unsafe.json?import&raw?&',
237+
),
238+
)
239+
.then((r) => {
240+
text('.unsafe-fs-fetch-raw-query2-status', r.status)
241+
return r.json()
242+
})
243+
.then((data) => {
244+
text('.unsafe-fs-fetch-raw-query2', JSON.stringify(data))
245+
})
246+
.catch((e) => {
247+
console.error(e)
248+
})
249+
212250
// outside root with special characters #8498
213251
fetch(
214252
joinUrlSegments(

0 commit comments

Comments
 (0)