Tech 4 min read

Critical vulnerabilities in pnpm < 10.26: Update now

Two critical vulnerabilities were found in pnpm 10.0.0–10.25. Both are rated High, and the RCE (remote code execution) one has a CVSS of 8.8, which is quite severe.

Bottom line: update to pnpm 10.26.0 or later immediately.

Vulnerability Summary

CVEDescriptionCVSSSeverity
CVE-2025-69263Lockfile integrity bypass7.5High
CVE-2025-69264Remote Code Execution (RCE)8.8High

Both issues are fixed in pnpm 10.26.0.

CVE-2025-69263: Lockfile Integrity Bypass

Root Cause

HTTP tarball dependencies and Git-hosted dependencies are stored in the lockfile without an integrity hash.

Normally, packages installed from the npm registry have a hash recorded in pnpm-lock.yaml and are verified on reinstall. However, HTTP tarball and Git dependencies are not verified.

# 通常のnpmパッケージ(ハッシュあり)
lodash@4.17.21:
  resolution: {integrity: sha512-...}

# HTTP tarball依存関係(ハッシュなし)
remote-pkg@http://example.com/pkg.tgz:
  resolution:
    tarball: http://example.com/pkg.tgz
  version: 1.0.0

Attack Scenario

  1. The attacker publishes a package that depends on an HTTP tarball

  2. It serves benign code during security audits

    • The attacker’s server decides based on IP, User-Agent, and timing
    • It delivers clean code to scanners and manual reviews
  3. It serves malicious code during CI/CD or production deploys

    • Detects CI environments like GitHub Actions or Jenkins
    • Delivers malicious code only for specific IP ranges (AWS, GCP, etc.)
  4. No hash in the lockfile means no verification

    • Even with the same lockfile, different code may be downloaded on each install

Why It’s Hard to Detect

  • The lockfile doesn’t change (no diffs)
  • Everything works fine on a developer’s local machine
  • Malicious code runs only in CI/CD environments
  • Re-downloading occurs after pnpm store prune, bypassing cache

CVE-2025-69264: Remote Code Execution (RCE)

Root Cause

pnpm v10 introduced a security feature that disables dependency lifecycle scripts by default. However, Git dependencies can completely bypass this protection.

Technical Details

In pnpm v10, a whitelist named onlyBuiltDependencies blocks scripts like postinstall.

pnpm install
 └─ BUILD フェーズ
     └─ onlyBuiltDependencies をチェック ← ここで postinstall をブロック

But Git dependencies are handled via a different path.

pnpm install
 └─ FETCH フェーズ
     └─ preparePackage() を呼び出し
         └─ onlyBuiltDependencies をチェックしない
         └─ prepare, prepublish, prepack が無条件実行

In other words, even if you rely on v10’s security feature and think “scripts are disabled, so it’s safe”, arbitrary code can still run via Git dependencies.

Attack Scenario

  1. The attacker plants a malicious script in a Git repository
{
  "name": "malicious-pkg",
  "scripts": {
    "prepare": "node -e \"require(fs).writeFileSync(/tmp/pwned, RCE)\""
  }
}
  1. The victim project depends on this package
    • It can be a transitive dependency; not just direct
{
  "dependencies": {
    "some-package": "github:attacker/malicious-pkg"
  }
}
  1. The victim runs pnpm install
    • The prepare script runs without warnings
    • pnpm v10’s security feature doesn’t apply

What an Attacker Can Do

  • Steal credentials: SSH keys, environment variables, .env files, API keys
  • Tamper with source: insert backdoors
  • Reverse shell: connect back to the attacker’s server
  • Persistence: register cron jobs or startup scripts

Impact in CI/CD

# GitHub Actions での典型的なワークフロー
- run: pnpm install  # ← ここで悪意あるコードが実行される

In CI/CD environments, the following are at risk of exfiltration:

  • GITHUB_TOKEN
  • Cloud credentials for AWS/GCP/Azure
  • Tokens used for npm publish
  • Deploy keys

Attackers can leverage these to escalate into a broader supply-chain attack.

Is My Project Affected?

Check Your Version

pnpm -v

You are affected if it’s 10.25 or earlier.

Check Your Dependencies

Look for dependencies like the following in your package.json.

// HTTP tarball(CVE-2025-69263)
"pkg": "https://example.com/pkg.tgz"

// Git shorthand(両方のCVEに該当)
"pkg": "github:user/repo"
"pkg": "gitlab:user/repo"
"pkg": "bitbucket:user/repo"

// Git URL(両方のCVEに該当)
"pkg": "git+https://github.com/user/repo.git"
"pkg": "git+ssh://git@github.com/user/repo.git"

If you only use packages from the npm registry (entries like "lodash": "^4.17.21"), the direct risk is lower. However, your dependencies may themselves pull in Git dependencies, so updating is still recommended.

Mitigation

Update pnpm

For global installs:

npm i -g pnpm@latest

If you use corepack:

corepack use pnpm@latest

Update package.json

Update the packageManager field if present.

{
  "packageManager": "pnpm@10.26.0"
}

Verify After Updating

pnpm -v
# Ensure it is 10.26.0 or newer

References