Skip to content

[Feature Request] Internal allowlist of @fs serving files #3373

@meteorlxy

Description

@meteorlxy

Description

Since v2.3.0, we restrcit access to filesystem to avoid secrity issues:

See #2820, #2850

However, this may cause potential breaks for projects using vite <2.3.0


There are some different types of fs url requests:

Type A - Files that users want to access intentionally.

For example, user writes import '/@fs/foo/bar/baz.js' explicitly in their code.

Users are responsible for their own code, so these kind of requests should NOT be restricted.

Setting server.fsServe.root could help, but we may only want to allow /@fs/foo/bar/baz.js file, instead of the whole parent path.

Type B - The resolved file path is outsite project root.

Example 1 (bare imports):

The project root is dev/:

export default {
  root: path.resolve(__dirname, 'dev')
}

import 'foo' in the dev/main.ts, then the resolved file is outside project root.

├── node_modules
|   └── foo         # resolved, outside project root
├── dev             # project root
|   ├── index.html
|   └── main.ts     # import 'foo' here
└── vite.config.ts

In addtion, npm link or npm install ../local-path should also cause this problem. (like #3347)

Example 2 (alias):

The project root is dev/, and set alias @some-alias:

export default {
  root: path.resolve(__dirname, 'dev')
  resolve: {
	alias: {
       '@some-alias': path.resolve(__dirname, 'src/index.ts')
    }
  }
}

import '@some-alias' in the dev/main.ts, then the resolved file is outside project root.

├── src
|   └── index.ts    # resolved, outside project root
├── dev             # project root
|   ├── index.html
|   └── main.ts     # import '@some-alias' here
└── vite.config.ts

These files are resolved according to the resolution rules, which should NOT be restricted.

Setting server.fsServe.root could help, but I think we should make it work by default without any extra configs.

Type C - Random traversal via url request

Visiting /@fs/ urls randomly, like #2820, #3281 reported.

This type of requests should be restricted.


I think Type C is the only thing that should be restricted by default, but now we simply restrict all fs requests outside project root.

Proposed Solution

As #3321 (comment) recommended, we can provide a configurable allowlist & disallowlist. This could help, but I think we should make Type A and Type B requests work out of the box.

I propose to also maintain an internal allowlist:

If a fs path is specified explicitly in source code (Type A), or resolved from the source code (Type B), we should add the path into the allowlist.

With the help of the internal allowlist, all intentional fs requests are allowed by default, and random visits are restricted.


In fact, Type A and Type B are somehow the same type: resolved fs path is outside the serve root - no matter it is wrote explicitly or resolved implicitly.

So we actually have two different situations:

  • Intentional fs requests from source code. (Allowed)
  • Unexpected fs requests from random visit. (Restricted)

In short, if we resolved a fs path from the source code, we should add it to the internal allowlist.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions