Skip to content

Commit 813ddd6

Browse files
authored
fix: fs.deny with leading double slash (#13348)
1 parent 28923fb commit 813ddd6

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function serveStaticMiddleware(
100100
return next()
101101
}
102102

103-
const url = new URL(req.url!, 'http://example.com')
103+
const url = new URL(req.url!.replace(/^\/+/, '/'), 'http://example.com')
104104
const pathname = decodeURIComponent(url.pathname)
105105

106106
// apply aliases to static requests as well
@@ -153,7 +153,7 @@ export function serveRawFsMiddleware(
153153

154154
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
155155
return function viteServeRawFsMiddleware(req, res, next) {
156-
const url = new URL(req.url!, 'http://example.com')
156+
const url = new URL(req.url!.replace(/^\/+/, '/'), 'http://example.com')
157157
// In some cases (e.g. linked monorepos) files outside of root will
158158
// reference assets that are also out of served root. In such cases
159159
// the paths are rewritten to `/@fs/` prefixed paths and must be served by

playground/assets-sanitize/.env

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KEY=unsafe

playground/assets-sanitize/__tests__/assets-sanitize.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ if (!isBuild) {
2525
expect(Object.keys(manifest).length).toBe(3) // 2 svg, 1 index.js
2626
})
2727
}
28+
29+
test.runIf(!isBuild)('denied .env', async () => {
30+
expect(await page.textContent('.unsafe-dotenv')).toBe('403')
31+
expect(await page.textContent('.unsafe-dotenv-double-slash')).toBe('403')
32+
})

playground/assets-sanitize/index.html

+30-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,35 @@
66
margin-bottom: 1rem;
77
}
88
</style>
9-
<h1>test elements below should show circles and their url</h1>
9+
<h3>test elements below should show circles and their url</h3>
1010
<div class="test-el plus-circle"></div>
1111
<div class="test-el underscore-circle"></div>
12+
13+
<h3>Denied .env</h3>
14+
<div class="unsafe-dotenv"></div>
15+
<div class="unsafe-dotenv-double-slash"></div>
16+
17+
<script type="module">
18+
// .env, denied by default. See fs-serve playground for other fs tests
19+
// these checks ensure that a project without a custom root respects fs.deny
20+
21+
fetch('/.env')
22+
.then((r) => {
23+
text('.unsafe-dotenv', r.status)
24+
})
25+
.catch((e) => {
26+
console.error(e)
27+
})
28+
29+
fetch(window.location + '/.env')
30+
.then((r) => {
31+
text('.unsafe-dotenv-double-slash', r.status)
32+
})
33+
.catch((e) => {
34+
console.error(e)
35+
})
36+
37+
function text(el, text) {
38+
document.querySelector(el).textContent = text
39+
}
40+
</script>

0 commit comments

Comments
 (0)