GHSA-QM8W-VX34-5J9J

Vulnerability from github – Published: 2026-10-30 14:42 – Updated: 2026-10-30 14:42
VLAI
Summary
@nx/maven and @nx/gradle have OS command injection via nx.json plugin options
Details

Summary

@nx/maven and @nx/gradle spawn their project-graph analyzers through a shell and interpolate plugin options read from nx.json straight into the command line. Because a shell parses the whole line, an option value containing shell syntax is executed as a command by any nx command that constructs the project graph. Anyone who clones a hostile repository, or who checks out a pull request that edits nx.json, runs the injected command with their own privileges.

Severity

A victim who runs an ordinary nx command in an attacker-supplied Maven or Gradle workspace gets code execution as themselves. In most such workspaces an attacker who can write nx.json can already run code through the repository's build files (./mvnw, pom.xml, and the Gradle equivalents), so the genuinely new exposure is narrow — for example CI building a fork's pull request where nx.json is writable but the build files are not. We have no evidence of exploitation in the wild.

Affected & Patched Versions

Package Vulnerable Patched
@nx/maven >= 22.0.2, < 22.7.9; >= 23.0.0, < 23.1.2 22.7.9, 23.1.2
@nx/gradle >= 21.0.0, < 22.7.9; >= 23.0.0, < 23.1.2 22.7.9, 23.1.2

[!IMPORTANT] Workspaces that register neither @nx/maven nor @nx/gradle in nx.json are unaffected — the vulnerable code only runs from those plugins' graph-construction paths, and no other Nx plugin shares this pattern.

Remediation

Upgrade to 22.7.9 (22.x line) or 23.1.2 (23.x line) or later:

nx migrate 23.1.2

Upgrade both nx and the affected plugin (@nx/maven and/or @nx/gradle). The plugin's fix depends on code that ships in the nx package, so bumping the plugin without a matching nx upgrade will not resolve it.

There is no configuration to change — upgrading is the whole fix. If you cannot upgrade yet, only run nx commands in repositories you trust, since a malicious nx.json can execute code on a vulnerable version.

Details

Both plugins spawn their analyzer through a shell and interpolate nx.json plugin options into the command, so those option values are shell source. For Maven the injectable value is the targetNamePrefix option; for Gradle it is broader, since every plugin option is mapped into a -P argument and arbitrary option names are accepted, making both the name and value of any option injectable.

Credits

  • Arkadiusz Marta (RE:SOURCE) — Reporter
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@nx/maven"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "22.0.2"
            },
            {
              "fixed": "22.7.9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@nx/maven"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "23.0.0"
            },
            {
              "fixed": "23.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@nx/gradle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "21.0.0"
            },
            {
              "fixed": "22.7.9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@nx/gradle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "23.0.0"
            },
            {
              "fixed": "23.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-119282"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-78",
      "CWE-88"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-30T14:42:14Z",
    "nvd_published_at": "2026-10-29T22:17:00Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\n`@nx/maven` and `@nx/gradle` spawn their project-graph analyzers through a shell and interpolate plugin options read from `nx.json` straight into the command line. Because a shell parses the whole line, an option value containing shell syntax is executed as a command by any `nx` command that constructs the project graph. Anyone who clones a hostile repository, or who checks out a pull request that edits `nx.json`, runs the injected command with their own privileges.\n\n## Severity\n\nA victim who runs an ordinary `nx` command in an attacker-supplied Maven or Gradle workspace gets code execution as themselves. In most such workspaces an attacker who can write `nx.json` can already run code through the repository\u0027s build files (`./mvnw`, `pom.xml`, and the Gradle equivalents), so the genuinely new exposure is narrow \u2014 for example CI building a fork\u0027s pull request where `nx.json` is writable but the build files are not. We have no evidence of exploitation in the wild.\n\n## Affected \u0026 Patched Versions\n\n| Package | Vulnerable | Patched |\n| --- | --- | --- |\n| `@nx/maven` | `\u003e= 22.0.2, \u003c 22.7.9`; `\u003e= 23.0.0, \u003c 23.1.2` | `22.7.9`, `23.1.2` |\n| `@nx/gradle` | `\u003e= 21.0.0, \u003c 22.7.9`; `\u003e= 23.0.0, \u003c 23.1.2` | `22.7.9`, `23.1.2` |\n\n\u003e [!IMPORTANT]\n\u003e Workspaces that register neither `@nx/maven` nor `@nx/gradle` in `nx.json` are unaffected \u2014 the vulnerable code only runs from those plugins\u0027 graph-construction paths, and no other Nx plugin shares this pattern.\n\n## Remediation\n\nUpgrade to **22.7.9** (22.x line) or **23.1.2** (23.x line) or later:\n\n```\nnx migrate 23.1.2\n```\n\nUpgrade both `nx` and the affected plugin (`@nx/maven` and/or `@nx/gradle`). The plugin\u0027s fix depends on code that ships in the `nx` package, so bumping the plugin without a matching `nx` upgrade will not resolve it.\n\nThere is no configuration to change \u2014 upgrading is the whole fix. If you cannot upgrade yet, only run `nx` commands in repositories you trust, since a malicious `nx.json` can execute code on a vulnerable version.\n\n## Details\n\nBoth plugins spawn their analyzer through a shell and interpolate `nx.json` plugin options into the command, so those option values are shell source. For Maven the injectable value is the `targetNamePrefix` option; for Gradle it is broader, since every plugin option is mapped into a `-P` argument and arbitrary option names are accepted, making both the name and value of any option injectable.\n\n## Credits\n\n- **Arkadiusz Marta** (RE:SOURCE) \u2014 Reporter",
  "id": "GHSA-qm8w-vx34-5j9j",
  "modified": "2026-10-30T14:42:14Z",
  "published": "2026-10-30T14:42:14Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/security/advisories/GHSA-qm8w-vx34-5j9j"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-119282"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/pull/36626"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/commit/02c5d59e8dbbbe30963c0181c6a22cd8c1190a25"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/commit/60196b7cfcffcada35b6b90e53bf1a78d049b548"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/commit/c227f4780b054c512965c73aa480a48f9f781409"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nrwl/nx"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/releases/tag/22.7.9"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nrwl/nx/releases/tag/23.1.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "@nx/maven and @nx/gradle have OS command injection via nx.json plugin options"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.