Skip to content

Dev server returns 403 for files with colon (:) in their path on Linux and macOS #23620

Description

@ragulka

Describe the bug

I am using colons in some paths for auto-generated files (using Laravel Wayfinder), which contain colons in route file names. These imports fail, because vite rejects any path with a colon in it.

Since #22572, isFileLoadingAllowed rejects any path that contains : while server.fs.strict is on. The check runs on every OS, but : is a valid character in file and folder names on Linux and macOS.

On 8.3.1 this breaks:

The server log also says the file is "outside of Vite serving allow list", then lists the folder that contains it.

Like I said, I ran into this with Laravel Wayfinder, which names route folders after route names, for example routes/company:logo/index.ts.

The ~ check from the same PR runs only on Windows, but the : check runs everywhere, which makes me think whether it was meant to cover NTFS volumes mounted on Linux or macOS?

I have a fix on a branch and I'd like to send a PR:

  • Keep rejecting : on Windows, where it can never be part of a file name.
  • On other OS-es, allow :, but also check the path with the stream part removed against server.fs.deny. So .env::$DATA is checked as .env and is still denied.

The trade-off: on an NTFS volume mounted on Linux or macOS, the streams of a file that is allowed and not denied become readable again, as they were before #22572. Would you accept that, or do you prefer a different approach?

I totally get it if you'd like to keep the behavior consistent across different OS-es, but I though this is at least worth a discussion?

Reproduction

https://github.com/ragulka/vite-colon-path-repro

Steps to reproduce

  1. Clone the reproduction and start the dev server:

    git clone https://github.com/ragulka/vite-colon-path-repro.git
    cd vite-colon-path-repro
    pnpm install
    pnpm dev
  2. Open http://localhost:5173.

    Expected: loaded: route:name
    Actual: failed: Failed to fetch dynamically imported module: http://localhost:5173/src/route:name/index.js

    Requesting the file directly gives the same result:

    curl -i http://localhost:5173/src/route:name/index.js
    # HTTP/1.1 403 Forbidden
  3. To see the folder case, clone the same repo into a folder with : in its name:

    git clone https://github.com/ragulka/vite-colon-path-repro.git 'my:app'
    cd 'my:app'
    pnpm install
    pnpm dev

    Open http://localhost:5173. Every file returns 403, including index.html, so the page doesn't load.

System Info

System:
    OS: macOS 27.0.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 366.94 MB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.22.2 - /Users/ragulka/.nvm/versions/node/v22.22.2/bin/node
    npm: 10.9.7 - /Users/ragulka/.nvm/versions/node/v22.22.2/bin/npm
    pnpm: 10.33.4 - /Users/ragulka/.nvm/versions/node/v22.22.2/bin/pnpm
    Deno: 2.7.1 - /opt/homebrew/bin/deno
  Browsers:
    Brave Browser: 153.1.95.101
    Chrome: 154.0.8037.92
    Firefox: 123.0.1
    Firefox Developer Edition: 153.0
    Safari: 27.0.1
  npmPackages:
    @vitejs/plugin-vue: ^6.0.8 => 6.0.8 
    vite: ^8.2.1 => 8.2.1

Used Package Manager

pnpm

Logs

No response

Validations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions