[Security] Bump vite from 5.2.11 to 5.4.18
Bumps vite from 5.2.11 to 5.4.18. This update includes security fixes.
Vulnerabilities fixed
Vite's
server.fs.deny
is bypassed when using?import&raw
Summary
The contents of arbitrary files can be returned to the browser.
Details
@fs
denies access to files outside of Vite serving allow list. Adding?import&raw
to the URL bypasses this limitation and returns the file content if it exists.PoC
$ npm create vite@latest $ cd vite-project/ $ npm install $ npm run dev $ echo "top secret content" > /tmp/secret.txt expected behaviour $ curl "http://localhost:5173/@fs/tmp/secret.txt" <body> <h1>403 Restricted</h1> </tr></table>
... (truncated)
Patched versions: 5.1.8; 5.2.14; 3.2.11; 4.5.4; 5.3.6; 5.4.6 Affected versions: >= 5.0.0, = 5.4.0, <= 5.4.5
Vite DOM Clobbering gadget found in vite bundled scripts that leads to XSS
Summary
We discovered a DOM Clobbering vulnerability in Vite when building scripts to
cjs
/iife
/umd
output format. The DOM Clobbering gadget in the module can lead to cross-site scripting (XSS) in web pages where scriptless attacker-controlled HTML elements (e.g., an img tag with an unsanitized name attribute) are present.Note that, we have identified similar security issues in Webpack: https://github.com/webpack/webpack/security/advisories/GHSA-4vvj-4cpr-p986
Details
Backgrounds
DOM Clobbering is a type of code-reuse attack where the attacker first embeds a piece of non-script, seemingly benign HTML markups in the webpage (e.g. through a post or comment) and leverages the gadgets (pieces of js code) living in the existing javascript code to transform it into executable code. More for information about DOM Clobbering, here are some references:
[1] https://scnps.co/papers/sp23_domclob.pdf [2] https://research.securitum.com/xss-in-amp4email-dom-clobbering/
Gadgets found in Vite
We have identified a DOM Clobbering vulnerability in Vite bundled scripts, particularly when the scripts dynamically import other scripts from the assets folder and the developer sets the build output format to
cjs
,iife
, orumd
. In such cases, Vite replaces relative paths starting with__VITE_ASSET__
using the URL retrieved fromdocument.currentScript
.However, this implementation is vulnerable to a DOM Clobbering attack. The
document.currentScript
lookup can be shadowed by an attacker via the browser's named DOM tree element access mechanism. This manipulation allows an attacker to replace the intended script element with a malicious HTML element. When this happens, the src attribute of the attacker-controlled element is used as the URL for importing scripts, potentially leading to the dynamic loading of scripts from an attacker-controlled server.
... (truncated)
Patched versions: 5.1.8; 3.2.11; 5.2.14; 5.3.6; 5.4.6; 4.5.4 Affected versions: >= 5.0.0, = 4.0.0, < 4.5.4
Websites were able to send any requests to the development server and read the response in vite
Summary
Vite allowed any websites to send any requests to the development server and read the response due to default CORS settings and lack of validation on the Origin header for WebSocket connections.
[!WARNING] This vulnerability even applies to users that only run the Vite dev server on the local machine and does not expose the dev server to the network.
Upgrade Path
Users that does not match either of the following conditions should be able to upgrade to a newer version of Vite that fixes the vulnerability without any additional configuration.
- Using the backend integration feature
- Using a reverse proxy in front of Vite
- Accessing the development server via a domain other than
localhost
or*.localhost
- Using a plugin / framework that connects to the WebSocket server on their own from the browser
Using the backend integration feature
If you are using the backend integration feature and not setting
server.origin
, you need to add the origin of the backend server to theserver.cors.origin
option. Make sure to set a specific origin rather than*
, otherwise any origin can access your development server.Using a reverse proxy in front of Vite
If you are using a reverse proxy in front of Vite and sending requests to Vite with a hostname other than
localhost
or*.localhost
, you need to add the hostname to the newserver.allowedHosts
option. For example, if the reverse proxy is sending requests tohttp://vite:5173
, you need to addvite
to theserver.allowedHosts
option.
... (truncated)
Patched versions: 4.5.6; 5.4.12; 6.0.9 Affected versions: = 6.0.0, <= 6.0.8
Vite bypasses server.fs.deny when using ?raw??
Summary
The contents of arbitrary files can be returned to the browser.
Impact
Only apps explicitly exposing the Vite dev server to the network (using
--host
orserver.host
config option) are affected.Details
@fs
denies access to files outside of Vite serving allow list. Adding?raw??
or?import&raw??
to the URL bypasses this limitation and returns the file content if it exists. This bypass exists because trailing separators such as?
are removed in several places, but are not accounted for in query string regexes.PoC
$ npm create vite@latest $ cd vite-project/ $ npm install $ npm run dev $ echo "top secret content" > /tmp/secret.txt expected behaviour $ curl "http://localhost:5173/@fs/tmp/secret.txt" </tr></table>
... (truncated)
Patched versions: 4.5.10; 5.4.15; 6.0.12; 6.1.2; 6.2.3 Affected versions: = 6.2.0, < 6.2.3
Vite has a
server.fs.deny
bypassed forinline
andraw
with?import
querySummary
The contents of arbitrary files can be returned to the browser.
Impact
Only apps explicitly exposing the Vite dev server to the network (using
--host
orserver.host
config option) are affected.Details
- base64 encoded content of non-allowed files is exposed using
?inline&import
(originally reported as?import&?inline=1.wasm?init
)- content of non-allowed files is exposed using
?raw?import
/@fs/
isn't needed to reproduce the issue for files inside the project root.PoC
Original report (check details above for simplified cases):
The ?import&?inline=1.wasm?init ending allows attackers to read arbitrary files and returns the file content if it exists. Base64 decoding needs to be performed twice
</tr></table>
... (truncated)
Patched versions: 4.5.11; 5.4.16; 6.0.13; 6.1.3; 6.2.4 Affected versions: = 6.2.0, < 6.2.4
Vite allows server.fs.deny to be bypassed with .svg or relative paths
Summary
The contents of arbitrary files can be returned to the browser.
Impact
Only apps explicitly exposing the Vite dev server to the network (using --host or server.host config option) are affected..
Details
.svg
Requests ending with
.svg
are loaded at this line. https://github.com/vitejs/vite/blob/037f801075ec35bb6e52145d659f71a23813c48f/packages/vite/src/node/plugins/asset.ts#L285-L290 By adding?.svg
with?.wasm?init
or withsec-fetch-dest: script
header, the restriction was able to bypass.This bypass is only possible if the file is smaller than
build.assetsInlineLimit
(default: 4kB) and when using Vite 6.0+.relative paths
... (truncated)
Patched versions: 4.5.12; 5.4.17; 6.0.14; 6.1.4; 6.2.5 Affected versions: = 6.2.0, < 6.2.5
Changelog
Sourced from vite's changelog.
5.4.18 (2025-04-10)
- fix: backport #19830, reject requests with
#
in request-target (#19831) (823675b), closes #19830 #198315.4.17 (2025-04-03)
5.4.16 (2025-03-31)
5.4.15 (2025-03-24)
5.4.14 (2025-01-21)
- fix:
preview.allowedHosts
with specific values was not respected (#19246) (9df6e6b), closes #19246- fix: allow CORS from loopback addresses by default (#19249) (7d1699c), closes #19249
5.4.13 (2025-01-20)
5.4.12 (2025-01-20)
- fix!: check host header to prevent DNS rebinding attacks and introduce
server.allowedHosts
(9da4abc)- fix!: default
server.cors: false
to disallow fetching from untrusted origins (dfea38f)- fix: verify token for HMR WebSocket connection (b71a5c8)
- chore: add deps update changelog (ecd2375)
5.4.11 (2024-11-11)
... (truncated)
Commits
-
731b77d
release: v5.4.18 -
823675b
fix: backport #19830, reject requests with#
in request-target (#19831) -
0a2518a
release: v5.4.17 -
84b2b46
fix: backport #19782, fs check with svg and relative paths (#19784) -
712cb71
release: v5.4.16 -
b627c50
fix: backport #19761, fs check in transform middleware (#19762) -
9b0f4c8
release: v5.4.15 -
807d7f0
fix: backport #19702, fs raw query with query separators (#19703) -
e7eb3c5
release: v5.4.14 -
7d1699c
fix: allow CORS from loopback addresses by default (#19249) - Additional commits viewable in compare view