Path traversal in unjs/storage leads to code injection due to unsanitzed code generation in unjs/nitro


Reported on

Jul 27th 2022

Path Traversal

A path traversal vulnerability exists within unjs/unstorage when using the file system storage driver.

This vulnerability can be exploited when the user has control over the key name. By creating key names containing sequences of ../ or ..: we can navigate the file system.

We are able to use : as a substitute to / due to this line.

Static Code Injection

When generating production builds, nitro bundles assets, here is an example of this output:

const _assets = {
  ['server:whatever.json']: {
    import: // ...
    meta: // ...

The filename in this output is not sanitized, this allows us to output code in the final bundle by using specially crafted file names.

For example, a file called ' + (()=>{console.log('hacked');return ''})() + ' will produce the following output.

const _assets = {
  ['server:' + (()=>{console.log('hacked');return ''})() + '.json']: {
    import: // ...
    meta: // ...

(the same issue exists within the import statement, but it has been omitted to keep it simple.)

It is important to note that we MUST generate valid code, or the build will fail.

Path Traversal In Nitro

When using a cached event handler in Nitro in development mode, a json file is placed on the file system, containing cache information. This path is influenced by the file path in the request.

This can also happen in production mode if the configuration is changed, but file system storage is default for cache in development mode.

In a scenario where there is a cached event handler, on a wildcard path, we can place .json files with arbitary names on the file system by constructing a path prefixed with ..:.

This would happen if:

  • A cached event handler is defined on a [name].ts route or [...].ts route.
  • SWR is applied to a [name].ts route or [...].ts route. (caching api)

Proof of concept

The following must be true for the proof of concept to work.

  1. Target is running a development server on linux.
  2. Target has a cached wildcard event handler.
  3. Target can be influenced to run a production build.


This is an example of an impacted configuration:

// nitro.config.ts
import { defineNitroConfig } from "nitropack";

export default defineNitroConfig({
    routes: {
        '**': { swr: true }

// /routes/[...].ts
export default () => `Wildcard!`


  1. Make a request to http://localhost:3000/..:..:..:..:..:assets:' + (()=>{console.log('hacked');return ''})() + 'while running in DEVELOPMENT mode (or convince user to place specially crafted file in assets directory)
  2. Convince, or wait for user to start a production build.
  3. Convince, or wait for user to run production build.
  4. Profit!


Due to the way code generation is done in nitro and nuxt this vulnerability likely occurs in many other places where a specially crafted file name can be placed within the project. This is the only example I could find that doesn't require a user to insert it themself.


This vulnerability is capable of RCE on target.

We are processing your report and will contact the unjs/nitro team within 24 hours. 2 years ago
OhB00 modified the report
2 years ago
We have contacted a member of the unjs/nitro team and are waiting to hear back 2 years ago
2 years ago


I've found quite a few different variations of this, none that you can trigger automatically, should I include these in the report ?

We have sent a follow up to the unjs/nitro team. We will try again in 4 days. 2 years ago
2 years ago


Has been patched in latest commits.

We have sent a second follow up to the unjs/nitro team. We will try again in 7 days. 2 years ago
2 years ago


@admin has been fixed but report not closed

We have sent a third follow up to the unjs/nitro team. We will try again in 14 days. 2 years ago
pooya parsa validated this vulnerability 2 years ago
ohb00 has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
pooya parsa marked this as fixed in unstorage@3.x, unstorage@4.x and unstorage@5.x, nitrpack@0.4.13 with commit 7aaab6 2 years ago
The fix bounty has been dropped
pooya parsa gave praise 2 years ago
Thanks for reporting the issue and follow-ups <3
The researcher's credibility has slightly increased as a result of the maintainer's thanks: +1
to join this conversation