fix: fs.deny with leading double slash (#13348) · vitejs/vite@7b61464

File tree

4 files changed

lines changed

  • packages/vite/src/node/server/middlewares

  • playground/assets-sanitize

4 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -96,7 +96,7 @@ export function serveStaticMiddleware(

9696

return next()

9797

}

9898
99-

const url = new URL(req.url!, 'http://example.com')

99+

const url = new URL(req.url!.replace(/^\/+/, '/'), 'http://example.com')

100100

const pathname = decodeURIComponent(url.pathname)

101101
102102

// apply aliases to static requests as well

@@ -146,7 +146,7 @@ export function serveRawFsMiddleware(

146146
147147

// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`

148148

return function viteServeRawFsMiddleware(req, res, next) {

149-

const url = new URL(req.url!, 'http://example.com')

149+

const url = new URL(req.url!.replace(/^\/+/, '/'), 'http://example.com')

150150

// In some cases (e.g. linked monorepos) files outside of root will

151151

// reference assets that are also out of served root. In such cases

152152

// the paths are rewritten to `/@fs/` prefixed paths and must be served by

Original file line numberDiff line numberDiff line change

@@ -0,0 +1 @@

1+

KEY=unsafe

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+

})

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>