Skip to content

"deleteOutDir" can recursively delete paths outside the project #3454

@AdrianoCLeao

Description

@AdrianoCLeao

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When compilerOptions.deleteOutDir is enabled, the CLI recursively removes the TypeScript outDir
without validating that it is inside the workspace. It also removes tsBuildInfoFile without
confinement.

An attacker can publish a repository with a crafted tsconfig.build.json and nest-cli.json. A user
who runs nest build can unknowingly delete writable files outside the checkout. The safe
reproduction targets a sibling directory, but the same issue applies to any writable path configured
as outDir or tsBuildInfoFile.

This is problematic in benign coding environments but with bad practices. If someone with less experience updates "outDir" to a relative path, it can compromise the entire team.

Relevant code:

  • actions/build.action.ts:123 calls deleteOutDirIfEnabled before compilation.
  • lib/compiler/helpers/delete-out-dir.ts:14-20 runs rm(dirPath, { recursive: true, force: true }).
  • lib/compiler/helpers/delete-out-dir.ts:21-23 removes tsOptions.tsBuildInfoFile.
  • test/lib/compiler/helpers/delete-out-dir.spec.ts:39-60 covers benign values such as dist but
    not absolute or parent-traversal paths.

Minimum reproduction code

"outDir": "../nest-cli-delete-outside",

Steps to reproduce

  1. Create a disposable Nest project.
  2. Create the sibling directory ../nest-cli-delete-outside and place a harmless file in it.
  3. Add the nest-cli.json and tsconfig.build.json shown bellow.
  4. Run nest build.
  5. Observe that the sibling directory is removed before compilation.

nest-cli.json:

{
  "compilerOptions": {
    "deleteOutDir": true
  }
}

tsconfig.build.json:

{
  "compilerOptions": {
    "outDir": "../nest-cli-delete-outside",
    "tsBuildInfoFile": "../nest-cli-delete-build-info.tsbuildinfo"
  },
  "include": ["src/**/*.ts"]
}

Expected behavior

The CLI should refuse to recursively remove paths outside the project workspace unless the user opts
into an explicit unsafe mode with clear confirmation.

Package version

11.0.21

NestJS version

Not application-specific.

Node.js version

22.20.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions