Skip to content

Commit b835699

Browse files
authoredJul 8, 2022
fix: re-encode url to prevent fs.allow bypass (fixes #8498) (#8979)
1 parent 5c6cf5a commit b835699

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed
 

‎packages/vite/src/node/server/middlewares/static.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export function serveStaticMiddleware(
109109
}
110110

111111
if (redirected) {
112-
req.url = redirected
112+
req.url = encodeURIComponent(redirected)
113113
}
114114

115115
serve(req, res, next)
@@ -144,7 +144,7 @@ export function serveRawFsMiddleware(
144144
url = url.slice(FS_PREFIX.length)
145145
if (isWindows) url = url.replace(/^[A-Z]:/i, '')
146146

147-
req.url = url
147+
req.url = encodeURIComponent(url)
148148
serveFromRoot(req, res, next)
149149
} else {
150150
next()

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

+10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ describe.runIf(isServe)('main', () => {
4242
expect(await page.textContent('.unsafe-fetch-8498-status')).toBe('403')
4343
})
4444

45+
test('unsafe fetch with special characters 2 (#8498)', async () => {
46+
expect(await page.textContent('.unsafe-fetch-8498-2')).toMatch('')
47+
expect(await page.textContent('.unsafe-fetch-8498-2-status')).toBe('404')
48+
})
49+
4550
test('safe fs fetch', async () => {
4651
expect(await page.textContent('.safe-fs-fetch')).toBe(stringified)
4752
expect(await page.textContent('.safe-fs-fetch-status')).toBe('200')
@@ -64,6 +69,11 @@ describe.runIf(isServe)('main', () => {
6469
expect(await page.textContent('.unsafe-fs-fetch-8498-status')).toBe('403')
6570
})
6671

72+
test('unsafe fs fetch with special characters 2 (#8498)', async () => {
73+
expect(await page.textContent('.unsafe-fs-fetch-8498-2')).toBe('')
74+
expect(await page.textContent('.unsafe-fs-fetch-8498-2-status')).toBe('404')
75+
})
76+
6777
test('nested entry', async () => {
6878
expect(await page.textContent('.nested-entry')).toBe('foobar')
6979
})

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

+29
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ <h2>Unsafe Fetch</h2>
1919
<pre class="unsafe-fetch"></pre>
2020
<pre class="unsafe-fetch-8498-status"></pre>
2121
<pre class="unsafe-fetch-8498"></pre>
22+
<pre class="unsafe-fetch-8498-2-status"></pre>
23+
<pre class="unsafe-fetch-8498-2"></pre>
2224

2325
<h2>Safe /@fs/ Fetch</h2>
2426
<pre class="safe-fs-fetch-status"></pre>
@@ -31,6 +33,8 @@ <h2>Unsafe /@fs/ Fetch</h2>
3133
<pre class="unsafe-fs-fetch"></pre>
3234
<pre class="unsafe-fs-fetch-8498-status"></pre>
3335
<pre class="unsafe-fs-fetch-8498"></pre>
36+
<pre class="unsafe-fs-fetch-8498-2-status"></pre>
37+
<pre class="unsafe-fs-fetch-8498-2"></pre>
3438

3539
<h2>Nested Entry</h2>
3640
<pre class="nested-entry"></pre>
@@ -100,6 +104,19 @@ <h2>Denied</h2>
100104
console.error(e)
101105
})
102106

107+
// outside of allowed dir with special characters 2 #8498
108+
fetch('/src/%252e%252e%252funsafe%252etxt')
109+
.then((r) => {
110+
text('.unsafe-fetch-8498-2-status', r.status)
111+
return r.text()
112+
})
113+
.then((data) => {
114+
text('.unsafe-fetch-8498-2', data)
115+
})
116+
.catch((e) => {
117+
console.error(e)
118+
})
119+
103120
// imported before, should be treated as safe
104121
fetch('/@fs/' + ROOT + '/safe.json')
105122
.then((r) => {
@@ -133,6 +150,18 @@ <h2>Denied</h2>
133150
text('.unsafe-fs-fetch-8498', JSON.stringify(data))
134151
})
135152

153+
// outside root with special characters 2 #8498
154+
fetch(
155+
'/@fs/' + ROOT + '/root/src/%252e%252e%252f%252e%252e%252funsafe%252ejson'
156+
)
157+
.then((r) => {
158+
text('.unsafe-fs-fetch-8498-2-status', r.status)
159+
return r.json()
160+
})
161+
.then((data) => {
162+
text('.unsafe-fs-fetch-8498-2', JSON.stringify(data))
163+
})
164+
136165
// not imported before, inside root with special characters, treated as safe
137166
fetch(
138167
'/@fs/' +

0 commit comments

Comments
 (0)
Please sign in to comment.