CVE-2023-34092 (published 2023-06-01T17:15Z)

Vite provides frontend tooling. Prior to versions 2.9.16, 3.2.7, 4.0.5, 4.1.5, 4.2.3, and 4.3.9, Vite Server Options (`server.fs.deny`) can be bypassed using double forward-slash (//) allows any unauthenticated user to read file from the Vite root-path of the application including the default `fs.deny` settings (`['.env', '.env.*', '*.{crt,pem}']`). Only users explicitly exposing the Vite dev server to the network (using `--host` or `server.host` config option) are affected, and only files in the immediate Vite project root folder could be exposed. This issue is fixed in vite@4.3.9, vite@4.2.3, vite@4.1.5, vite@4.0.5, vite@3.2.7, and vite@2.9.16.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-706
cwe_name: Use of Incorrectly-Resolved Name or Reference
description: The product uses a name or reference to access a resource, but the name/reference resolves to a resource that is outside of the intended control sphere.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/vitejs/vite
commit_details: repo_url: https://github.com/vitejs/vite
author: patak
author_date: 2023-05-26 12:17:52+02:00
msg: fix: fs.deny with leading double slash (#13348)
repository: repo_url: https://github.com/vitejs/vite
repo_name: vitejs/vite
description: Next generation frontend tooling. It's fast!
repo_language: TypeScript
owner: vitejs
file_changes: filename: static.ts
change_type: ModificationType.MODIFY
diff: @@ -100,7 +100,7 @@ export function serveStaticMiddleware(
       return next()
     }
 
-    const url = new URL(req.url!, 'http://example.com')
+    const url = new URL(req.url!.replace(/^\/+/, '/'), 'http://example.com')
     const pathname = decodeURIComponent(url.pathname)
 
     // apply aliases to static requests as well
@@ -153,7 +153,7 @@ export function serveRawFsMiddleware(
 
   // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
   return function viteServeRawFsMiddleware(req, res, next) {
-    const url = new URL(req.url!, 'http://example.com')
+    const url = new URL(req.url!.replace(/^\/+/, '/'), 'http://example.com')
     // In some cases (e.g. linked monorepos) files outside of root will
     // reference assets that are also out of served root. In such cases
     // the paths are rewritten to `/@fs/` prefixed paths and must be served by

programming_language: TypeScript
filename: .env
change_type: ModificationType.ADD
diff: @@ -0,0 +1 @@
+KEY=unsafe

programming_language: SQL
filename: assets-sanitize.spec.ts
change_type: ModificationType.MODIFY
diff: @@ -25,3 +25,8 @@ if (!isBuild) {
     expect(Object.keys(manifest).length).toBe(3) // 2 svg, 1 index.js
   })
 }
+
+test.runIf(!isBuild)('denied .env', async () => {
+  expect(await page.textContent('.unsafe-dotenv')).toBe('403')
+  expect(await page.textContent('.unsafe-dotenv-double-slash')).toBe('403')
+})

programming_language: TypeScript
filename: index.html
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,35 @@
     margin-bottom: 1rem;
   }
 </style>
-<h1>test elements below should show circles and their url</h1>
+<h3>test elements below should show circles and their url</h3>
 <div class="test-el plus-circle"></div>
 <div class="test-el underscore-circle"></div>
+
+<h3>Denied .env</h3>
+<div class="unsafe-dotenv"></div>
+<div class="unsafe-dotenv-double-slash"></div>
+
+<script type="module">
+  // .env, denied by default. See fs-serve playground for other fs tests
+  // these checks ensure that a project without a custom root respects fs.deny
+
+  fetch('/.env')
+    .then((r) => {
+      text('.unsafe-dotenv', r.status)
+    })
+    .catch((e) => {
+      console.error(e)
+    })
+
+  fetch(window.location + '/.env')
+    .then((r) => {
+      text('.unsafe-dotenv-double-slash', r.status)
+    })
+    .catch((e) => {
+      console.error(e)
+    })
+
+  function text(el, text) {
+    document.querySelector(el).textContent = text
+  }
+</script>

programming_language: HTML