1.0.0 • Published 4 months ago

is-path-inside-secure v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

is-path-inside-secure

A symlink-aware implementation of the popular is-path-inside npm package.

A symlink-aware helper function that checks whether childPath is truly inside parentPath. Internally calls fs.realpathSync to follow symlinks. If either path doesn't exist, returns false. It then calls the original is-path-inside method.

Why build this and Usage

The original is-path-inside isn't symlink aware and has the following note:

Important: This package is meant for use with path manipulation. It does not check if the paths exist nor does it resolve symlinks. You should not use this as a security mechanism to guard against access to certain places on the file system.

The idea is to allow is-path-inside-secure to be used as a security mechanism.

The package also takes inspiration from Vercel's serve-handler, which is the NPM package protecting another popular Vercel static file server package @vercel/serve. (Note: @vercel/serve handles symlinks differently and doesn't need to handle that case within this check).

The package is also inspired by the fix from BackStage in this PR to address CVE-2024-26150.

You can refer to this research work here for more information.

A simple use case for the package would be where users can control whether or not a symlink can be created on the machine, and we don't want to serve sensitive files outside of a parent directory. The package would return true even for symlinks PROVIDED they are within the intended directory AND if the file/path it is pointing to exists. Since this also handles missing files, users can simply call the function, and it will return false, so they can directly return a 404 response.

const { isPathInsideSecure } = require('is-path-inside-secure');

router.route('/public/:file').get(function (req, res) {
  try {
    const { file } = req.params;
    // URIDecode parameter
    const decodedFile = decodeURIComponent(file);
    // Define the trusted root directory
    const rootDir = path.join(__dirname, '../../public');
    // Join the decoded path segments
    const absolutePath = path.join(rootDir, decodedFile);
    // Check if the resulting path stays inside rootDir
    // if not return 404
    if (!isPathInsideSecure(absolutePath, rootDir)) {
      console.log('Rejecting path. Absolute path resolved to:', absolutePath);
      return res.status(404).json({
        success: false,
        error: 'File could not be found',
      });
    }
    // Additional code to handle the file...
  } catch (error) {
    return res.status(503).json({
      success: false,
      result: null,
      message: error.message,
      error: error,
    });
  }
});

Install

npm install is-path-inside-secure

API

isPathInsideSecure(childPath, parentPath)

Note: Also, has the original is-path-inside API as well.

Checks for Symlinks and existence of path.

Type: string

The path that should be inside parentPath

Type: string

The path that should contain childPath.

1.0.0

4 months ago

1.0.4-beta

5 months ago

1.0.3-beta

5 months ago

1.0.2-beta

5 months ago

1.0.1-beta

5 months ago

1.0.0-beta

5 months ago