CVE-2026-104853
Nx: Path traversal in nx migrate package-migrations extraction
Nx is a monorepo solution for TypeScript and polyglot codebases. From 13.10.0 until 22.7.10 and 23.2.1, Nx migration planning reads the nx-migrations.migrations value from a target package manifest without validating that it is a contained relative path. A hostile direct dependency or a package introduced through a trusted package's packageGroup can supply .. segments or an absolute path, causing nx migrate to join an escaping destination onto its temporary directory. The migration archive can then write attacker-controlled bytes outside the temporary directory, while opening the destination stream can truncate an existing writable file even when no archive entry matches. This occurs during migration planning before review of the migration list or use of --run-migrations; the vulnerable installed Nx copy is reached when the normal nx@latest handoff is bypassed with NX_USE_LOCAL, NX_MIGRATE_USE_LOCAL, NX_MIGRATE_CLI_VERSION, --run-id, or fallback after a temporary-install failure. This issue is fixed in versions 22.7.10 and 23.2.1.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Passive
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.8
Nx: Path traversal in nx migrate package-migrations extraction
Nx is a monorepo solution for TypeScript and polyglot codebases. From 13.10.0 until 22.7.10 and 23.2.1, Nx migration planning reads the nx-migrations.migrations value from a target package manifest without validating that it is a contained relative path. A hostile direct dependency or a package introduced through a trusted package's packageGroup can supply .. segments or an absolute path, causing nx migrate to join an escaping destination onto its temporary directory. The migration archive can then write attacker-controlled bytes outside the temporary directory, while opening the destination stream can truncate an existing writable file even when no archive entry matches. This occurs during migration planning before review of the migration list or use of --run-migrations; the vulnerable installed Nx copy is reached when the normal nx@latest handoff is bypassed with NX_USE_LOCAL, NX_MIGRATE_USE_LOCAL, NX_MIGRATE_CLI_VERSION, --run-id, or fallback after a temporary-install failure. This issue is fixed in versions 22.7.10 and 23.2.1.
- Record
CVE-2026-104853- CVSS 4.0
- 5.8 Medium
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-22, CWE-73
- Updated
- 2026-11-02
EUVDEUVD-2026-91761
5.8
Nx is a monorepo solution for TypeScript and polyglot codebases. From 13.10.0 until 22.7.10 and 23.2.1, Nx migration planning reads the nx-migrations.migrations value from a target package manifest without validating that it is a contained relative path. A hostile direct dependency or a package introduced through a trusted package's packageGroup can supply .. segments or an absolute path, causing nx migrate to join an escaping destination onto its temporary directory. The migration archive can then write attacker-controlled bytes outside the temporary directory, while opening the destination stream can truncate an existing writable file even when no archive entry matches. This occurs during migration planning before review of the migration list or use of --run-migrations; the vulnerable installed Nx copy is reached when the normal nx@latest handoff is bypassed with NX_USE_LOCAL, NX_MIGRATE_USE_LOCAL, NX_MIGRATE_CLI_VERSION, --run-id, or fallback after a temporary-install failure. This issue is fixed in versions 22.7.10 and 23.2.1.
- Record
EUVD-2026-91761- CVSS 4.0
- 5.8 Medium
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-hrvq-x7jp-36xv
5.8
Nx: Path traversal in nx migrate package-migrations extraction
Summary
nx migrate reads each target package's nx-migrations.migrations value from its manifest and extracts the referenced file to a path built by joining that value onto a temporary directory. The value is never validated, so a package whose migrations field contains .. segments (or an absolute path) steers the extraction to write outside the temporary directory. A hostile package — or any package pulled in transitively through a trusted package's packageGroup — can write attacker-controlled content, or truncate an existing file, anywhere the running user can write. This happens during migration planning, before the user reviews the migration list and before --run-migrations, so it does not require the user to approve or execute anything.
Most workspaces need no action. By default nx migrate does not run the nx installed in your workspace — it installs nx@latest into a temporary directory and performs the upgrade planning, including this extraction, with that copy. Now that a patched nx is the latest release, a default nx migrate run is unaffected whatever version the workspace has installed. The installed version only runs, and is only then exposed, when that hand-off is bypassed — see Remediation.
Severity
Exploitable when the victim runs nx migrate against a package the attacker controls, directly or through a trusted package's packageGroup. The primary impact is a file write with attacker-controlled content and no path confinement; overwriting an auto-loaded file (a shell rc, a git hook, a CI script) escalates that write to code execution. There is no known evidence of exploitation in the wild.
Affected & Patched Versions
| Package | Vulnerable | Patched |
| --- | --- | --- |
| nx | >= 13.10.0, < 22.7.10; >= 23.0.0, < 23.2.1 | 22.7.10, 23.2.1 |
Every version in the ranges above is affected. The lower bound is 13.10.0, the first release where nx migrate extracted a package's migrations file from its tarball; earlier versions resolved migrations without that extraction.
[!IMPORTANT]
nx migratenormally fetches and runsnx@latestrather than the nx installed in your workspace. The ranges above therefore say where the vulnerable code ships, not who is exposed — it only runs when that hand-off is bypassed.
Remediation
If you run nx migrate normally, there is nothing to do. It resolves and runs the latest nx, which is patched, so your workspace's own nx version does not matter for this flaw.
Upgrade only if you bypass that hand-off and run the workspace's nx instead — that is, if you set NX_USE_LOCAL or NX_MIGRATE_USE_LOCAL, pin NX_MIGRATE_CLI_VERSION to an affected version, resume an existing run with --run-id, or run where the temporary install fails and nx migrate falls back to the local nx. In those cases upgrade to 22.7.10 (22.x line) or 23.2.1 (23.x line) or later:
nx migrate 23.2.1
The fix is a drop-in — no configuration changes are required, and no legitimate migrations value is affected (real packages reference ./migrations.json or another path within their own directory, all of which remain valid). Either way, do not run nx migrate against packages, or packageGroup members, that you do not trust.
Details
While planning an upgrade, nx migrate extracts each target package's migrations file to a destination built by joining the package's own nx-migrations.migrations value onto a temporary directory. That value is read from the manifest without validation, and it is handled asymmetrically: the name Nx matches against the archive entries is normalized (so its .. segments collapse), while the destination path it writes to is a raw join that keeps the .. segments and resolves outside the temporary directory. Because the attacker controls the tarball, they name their entry to equal the normalized form; the match then succeeds and the bytes are written to the un-normalized, escaping…
- Record
GHSA-hrvq-x7jp-36xv- CVSS 4.0
- 5.8 Medium
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-22, CWE-73
- Updated
- 2026-11-02
NVD
5.8
Nx is a monorepo solution for TypeScript and polyglot codebases. From 13.10.0 until 22.7.10 and 23.2.1, Nx migration planning reads the nx-migrations.migrations value from a target package manifest without validating that it is a contained relative path. A hostile direct dependency or a package introduced through a trusted package's packageGroup can supply .. segments or an absolute path, causing nx migrate to join an escaping destination onto its temporary directory. The migration archive can then write attacker-controlled bytes outside the temporary directory, while opening the destination stream can truncate an existing writable file even when no archive entry matches. This occurs during migration planning before review of the migration list or use of --run-migrations; the vulnerable installed Nx copy is reached when the normal nx@latest handoff is bypassed with NX_USE_LOCAL, NX_MIGRATE_USE_LOCAL, NX_MIGRATE_CLI_VERSION, --run-id, or fallback after a temporary-install failure. This issue is fixed in versions 22.7.10 and 23.2.1.
- Record
CVE-2026-104853- CVSS 4.0
- 5.8 Medium
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-22, CWE-73
- Updated
- 2026-11-02
OSV
5.8
Nx: Path traversal in nx migrate package-migrations extraction
Nx is a monorepo solution for TypeScript and polyglot codebases. From 13.10.0 until 22.7.10 and 23.2.1, Nx migration planning reads the nx-migrations.migrations value from a target package manifest without validating that it is a contained relative path. A hostile direct dependency or a package introduced through a trusted package's packageGroup can supply .. segments or an absolute path, causing nx migrate to join an escaping destination onto its temporary directory. The migration archive can then write attacker-controlled bytes outside the temporary directory, while opening the destination stream can truncate an existing writable file even when no archive entry matches. This occurs during migration planning before review of the migration list or use of --run-migrations; the vulnerable installed Nx copy is reached when the normal nx@latest handoff is bypassed with NX_USE_LOCAL, NX_MIGRATE_USE_LOCAL, NX_MIGRATE_CLI_VERSION, --run-id, or fallback after a temporary-install failure. This issue is fixed in versions 22.7.10 and 23.2.1.
- Record
CVE-2026-104853- CVSS 4.0
- 5.8 Medium
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-22, CWE-73
- Updated
- 2026-11-02
OSVGHSA-hrvq-x7jp-36xv
5.8
Nx: Path traversal in nx migrate package-migrations extraction
Summary
nx migrate reads each target package's nx-migrations.migrations value from its manifest and extracts the referenced file to a path built by joining that value onto a temporary directory. The value is never validated, so a package whose migrations field contains .. segments (or an absolute path) steers the extraction to write outside the temporary directory. A hostile package — or any package pulled in transitively through a trusted package's packageGroup — can write attacker-controlled content, or truncate an existing file, anywhere the running user can write. This happens during migration planning, before the user reviews the migration list and before --run-migrations, so it does not require the user to approve or execute anything.
Most workspaces need no action. By default nx migrate does not run the nx installed in your workspace — it installs nx@latest into a temporary directory and performs the upgrade planning, including this extraction, with that copy. Now that a patched nx is the latest release, a default nx migrate run is unaffected whatever version the workspace has installed. The installed version only runs, and is only then exposed, when that hand-off is bypassed — see Remediation.
Severity
Exploitable when the victim runs nx migrate against a package the attacker controls, directly or through a trusted package's packageGroup. The primary impact is a file write with attacker-controlled content and no path confinement; overwriting an auto-loaded file (a shell rc, a git hook, a CI script) escalates that write to code execution. There is no known evidence of exploitation in the wild.
Affected & Patched Versions
| Package | Vulnerable | Patched |
| --- | --- | --- |
| nx | >= 13.10.0, < 22.7.10; >= 23.0.0, < 23.2.1 | 22.7.10, 23.2.1 |
Every version in the ranges above is affected. The lower bound is 13.10.0, the first release where nx migrate extracted a package's migrations file from its tarball; earlier versions resolved migrations without that extraction.
[!IMPORTANT]
nx migratenormally fetches and runsnx@latestrather than the nx installed in your workspace. The ranges above therefore say where the vulnerable code ships, not who is exposed — it only runs when that hand-off is bypassed.
Remediation
If you run nx migrate normally, there is nothing to do. It resolves and runs the latest nx, which is patched, so your workspace's own nx version does not matter for this flaw.
Upgrade only if you bypass that hand-off and run the workspace's nx instead — that is, if you set NX_USE_LOCAL or NX_MIGRATE_USE_LOCAL, pin NX_MIGRATE_CLI_VERSION to an affected version, resume an existing run with --run-id, or run where the temporary install fails and nx migrate falls back to the local nx. In those cases upgrade to 22.7.10 (22.x line) or 23.2.1 (23.x line) or later:
nx migrate 23.2.1
The fix is a drop-in — no configuration changes are required, and no legitimate migrations value is affected (real packages reference ./migrations.json or another path within their own directory, all of which remain valid). Either way, do not run nx migrate against packages, or packageGroup members, that you do not trust.
Details
While planning an upgrade, nx migrate extracts each target package's migrations file to a destination built by joining the package's own nx-migrations.migrations value onto a temporary directory. That value is read from the manifest without validation, and it is handled asymmetrically: the name Nx matches against the archive entries is normalized (so its .. segments collapse), while the destination path it writes to is a raw join that keeps the .. segments and resolves outside the temporary directory. Because the attacker controls the tarball, they name their entry to equal the normalized form; the match then succeeds and the bytes are written to the un-normalized, escaping…
- Record
GHSA-hrvq-x7jp-36xv- CVSS 4.0
- 5.8 Medium
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-22, CWE-73
- Updated
- 2026-11-02
Affected products
Affected packages
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-104853 is a medium vulnerability (CVSS 5.8) in Nrwl Nx, published October 2, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.17%, the 6th percentile. Fixed in nx 22.7.10.
References
github.com/nrwl/nx/security/advisories/GHSA-hrvq-x7jp-36xv
github.com/nrwl/nx/pull/36887
github.com/nrwl/nx/commit/38cd82a0c05e8212e538bdb87ccb198d6504e58f
github.com/nrwl/nx/commit/95474ab457e8e1dbdbefad29040c166105a8fb90
github.com/nrwl/nx/commit/de37c5ebd1852fac700d70726326236ac398af3f
github.com/nrwl/nx/releases/tag/22.7.10
Left out here: the rest of 2 source descriptions. The JSON record has them.