← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-3219 · CWE-434 · Disclosed 2026-04-20

pip handles concatenated tar and ZIP files as ZIP files regardless of filename or whether a file is both a…

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a mislabeled shipping crate problem, not a crowbar through the front door

CVE-2026-3219 affects pip through version 26.0.1, fixed in 26.1. The vulnerable logic can treat a concatenated or ambiguously structured archive as a ZIP based on ZIP metadata even when the filename says .tar.gz, which can lead pip to install files that do not match the archive type an operator thought they were installing.

In practice this is not an internet-reachable break-in; it is a *victim-installs-an-attacker-controlled-artifact* problem. Even though current PSF/CNA-linked advisory data shows a 4.6 MEDIUM CVSSv4 score, the real-world chain is narrower than that headline suggests: the attacker needs control of the package artifact or delivery path, active user/CI interaction, and a workflow that accepts ambiguous archives in the first place.

"Low-severity supply-chain edge case: the attacker needs you to pip-install a deliberately ambiguous archive."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Craft an ambiguous archive with tar + zip metadata

The attacker prepares a package file that is valid enough for zipfile.is_zipfile() to trip while also presenting as a tar-based source distribution. The underlying bug is parser ambiguity: pip<=26.0.1 could prioritize ZIP handling even when the filename or operator expectation points to tar.
Conditions required:
  • Attacker can create and host a specially crafted package archive
  • Target workflow accepts archives outside a tightly controlled internal build pipeline
Where this breaks in practice:
  • Most enterprise package flows consume normal wheels from trusted indexes, not hand-crafted polyglot archives
  • Hash pinning, repository curation, and artifact signing reduce the chance that a crafted archive is accepted
Detection/coverage: Static scanners will not see the exploit chain in the archive itself unless they inspect the actual file. Version-based tools can only flag pip version exposure.
STEP 02

Deliver it through a package source the victim will trust

The archive must be referenced by a requirements.txt, direct URL, private index, compromised mirror, or local file path that the victim's pip install workflow will use. This is the decisive friction point: exploitation requires a supply-chain foothold or user-assisted delivery, not unauthenticated remote reachability.
Conditions required:
  • Victim runs pip against attacker-controlled or attacker-influenced package content
  • User or CI job performs installation
Where this breaks in practice:
  • Internal mirrors often whitelist packages and normalize artifacts
  • Modern CI usually builds from locked dependencies rather than arbitrary URLs or local archives
  • Email, browser, or chat delivery still needs a human or pipeline operator to execute the install
Detection/coverage: Proxy logs, index access logs, and CI build logs can show direct-URL installs or nonstandard package sources; vulnerability scanners generally cannot prove exploitability from SBOM data alone.
STEP 03

Trigger vulnerable unpacking in pip<=26.0.1

When the victim invokes pip, the vulnerable unpacking path can classify the file as ZIP and install the ZIP-interpreted contents rather than rejecting the ambiguity. The 26.1 fix changes this behavior so installation only continues when the file is uniquely identifiable as ZIP or tar.
Conditions required:
  • Installed pip version is 26.0.1 or earlier
  • The install path reaches archive unpacking rather than a previously built wheel
Where this breaks in practice:
  • If a wheel is used instead of an sdist/archive path, this specific bug is sidestepped
  • Tooling that pre-unpacks, validates, or repackages artifacts can break the chain before pip sees the ambiguous file
Detection/coverage: High coverage for exposure, low coverage for abuse: pip-audit, Dependabot, GitHub Advisory ingestion, and OSV consumers can flag vulnerable versions, but they do not tell you whether your org installs ambiguous archives.
STEP 04

Land integrity-impacting but narrow-scope results

The likely outcome is confusing or unintended file installation on the invoking workstation, CI runner, or build environment. That matters for supply-chain hygiene, but the blast radius is usually the single environment performing the install, not a remote fleet-wide service compromise by itself.
Conditions required:
  • Installed files influence a build, package output, or local developer environment
  • Downstream controls do not catch unexpected file layout or content
Where this breaks in practice:
  • Reproducible builds, artifact attestations, and post-build validation can catch drift
  • The vulnerability does not itself provide direct unauthenticated RCE against a network service
Detection/coverage: Best detected through build reproducibility checks, archive validation, and comparing expected package contents with installed results.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence of active exploitation found in the sources reviewed; not in CISA KEV per the prompt and no campaign reporting surfaced in the PSF/GHSA/NVD references.
Proof of concept availabilityPublic technical reproduction exists via issue #13867 and the fix discussion in PR #13870; this is enough for competent attackers to reproduce without a turnkey weaponized repo.
EPSS0.00018 from the prompt. GitHub Advisory/OSV currently display roughly 0.018% / 5th percentile, which is directionally consistent with very low near-term exploitation likelihood.
KEV statusNot KEV-listed as provided in the prompt. No override to immediate emergency patching based on KEV.
Current authoritative scoring noteThe prompt says there was no baseline, but as of 2026-04-20 the PSF CNA data shown by NVD and GitHub Advisory includes CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N = 4.6 MEDIUM.
Affected versionsAuthoritative package range is all pip versions through 26.0.1 per OSV and GitHub Advisory.
Fixed versionFixed in pip 26.1; the 26.1 changelog notes: fix installing .tar.gz source distributions that look like a zip file.
Exposure and scanning realityInference from product architecture: internet-wide scanners like Shodan/Censys/GreyNoise are largely irrelevant here because pip is a client-side package installer, not a remotely exposed daemon. Exposure is driven by where developers, CI runners, base images, and bootstrap scripts execute pip against untrusted archives.
Disclosure timelineBug reported in issue #13867 on 2026-03-26; fix merged in PR #13870 on 2026-04-19; CVE/advisory published 2026-04-20 via PSF security-announce.
Reporter / analyst attributionThe original bug reporter and patch author shown in GitHub is f3flight. GitHub Advisory credits amine-malloul-gira and tsokalski as analysts; PSF announcement was sent by Seth Larson.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.1/10)

The single biggest downgrade driver is attacker position: this is *not* unauthenticated remote exploitation, it is a supply-chain or user-assisted install path that requires the victim to run pip on an attacker-controlled ambiguous archive. That sharply limits reachable population and turns the issue into build/workstation integrity risk rather than broad fleet compromise.

HIGH Exploit preconditions are narrow and require user/CI-assisted package installation
HIGH No meaningful internet-exposed attack surface exists for this client-side utility flaw
MEDIUM Downstream impact varies by how much your build pipeline trusts direct URLs, sdists, and local archives

Why this verdict

  • Attacker position downgrade: exploitation requires control of the package artifact or delivery path plus a victim-initiated pip install. That means post-social-engineering or post-supply-chain foothold, not first-stage remote compromise.
  • Exposure population downgrade: pip is everywhere, but the vulnerable path only matters where teams ingest untrusted or non-normalized archives. Enterprises that mostly install wheels from PyPI or internal mirrors with hashes are exposed on paper but much less reachable in practice.
  • Blast radius downgrade: the direct impact is low-integrity confusion on the invoking host or CI runner, not guaranteed code execution against a server process. The compromise scope is usually one workstation, one image build, or one pipeline run.

Why not higher?

A higher rating would fit if this were remotely triggerable against a service or if the bug reliably yielded arbitrary file write or code execution on every install. The available sources describe confusing or incorrect installation behavior with local attack vector and active user interaction, which is materially narrower.

Why not lower?

It is still a real security flaw in a ubiquitous package manager, not mere cosmetic mislabeling. In organizations that consume third-party sdists, direct URLs, or locally staged archives in CI, ambiguous parsing can undermine package integrity assumptions and taint build outputs.

05 · Compensating Control

What to do — in priority order.

  1. Prefer wheels and pinned hashes — Force builds to consume curated wheel artifacts or hash-pinned packages from approved indexes. For a LOW verdict there is no formal mitigation SLA; treat this as backlog hygiene and implement during the next normal packaging-policy refresh.
  2. Block direct-URL and local-archive installs in CI — Disallow pip install from arbitrary URLs, local file drops, or ad hoc archive paths in shared runners unless explicitly approved. This removes the easiest delivery path for ambiguous archives; for LOW, fold it into standard pipeline hardening work rather than emergency change windows.
  3. Centralize package sources — Use an internal mirror or artifact repository that normalizes, scans, and records package content before developers or CI consume it. That pushes ambiguity handling out of end-user workstations and into a controllable choke point; again, no LOW mitigation SLA applies.
  4. Upgrade bootstrap images and venv seeds to pip>=26.1 — Refresh base images, devcontainers, golden workstations, and virtualenv seed packages so new environments stop inheriting vulnerable pip versions. For LOW, do this in the next routine toolchain uplift rather than as an out-of-band emergency patch.
What doesn't work
  • A WAF or edge firewall does not help because there is no remotely exposed service path to filter.
  • Endpoint AV alone is not a reliable control here; the problem is parser ambiguity during package installation, not a known malware signature.
  • MFA does nothing once a developer or CI job is already running pip on the attacker-controlled archive.
06 · Verification

Crowdsourced verification payload.

Run this on the target workstation, CI runner, container image, or base Python environment you want to assess. Invoke it with the same interpreter whose pip you care about, for example python verify_cve_2026_3219.py; no admin rights are required, and it checks the installed pip version in the current environment.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
"""
CVE-2026-3219 verifier for pip.
Outputs one of: VULNERABLE / PATCHED / UNKNOWN
Exit codes:
  0 = PATCHED
  1 = VULNERABLE
  2 = UNKNOWN
"""

from __future__ import annotations

import re
import sys

try:
    try:
        from importlib import metadata as importlib_metadata
    except Exception:
        import importlib_metadata  # type: ignore
except Exception:
    print("UNKNOWN - unable to import package metadata support")
    sys.exit(2)


def parse_version(v: str):
    """Very small parser sufficient for pip versions like 26.0.1 or 26.1."""
    if not v or not isinstance(v, str):
        return None
    m = re.match(r"^(\d+)(?:\.(\d+))?(?:\.(\d+))?", v)
    if not m:
        return None
    parts = [int(p) if p is not None else 0 for p in m.groups()]
    while len(parts) < 3:
        parts.append(0)
    return tuple(parts[:3])


def main():
    try:
        version = importlib_metadata.version("pip")
    except Exception as exc:
        print(f"UNKNOWN - could not determine installed pip version: {exc}")
        sys.exit(2)

    parsed = parse_version(version)
    fixed = (26, 1, 0)
    if parsed is None:
        print(f"UNKNOWN - unparseable pip version: {version}")
        sys.exit(2)

    if parsed < fixed:
        print(f"VULNERABLE - installed pip version {version} is earlier than 26.1")
        sys.exit(1)
    else:
        print(f"PATCHED - installed pip version {version} is 26.1 or later")
        sys.exit(0)


if __name__ == "__main__":
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, inventory where pip actually runs in your estate: developer workstations, CI runners, base container images, venv bootstrap paths, and any automation that installs from direct URLs or local archives. Because this is LOW, there is no noisgate mitigation SLA and no noisgate remediation SLA beyond backlog hygiene; queue pip>=26.1 into the next routine toolchain refresh, but prioritize only the subsets that ingest untrusted sdists or ad hoc archive paths rather than fleets that install solely from pinned internal mirrors.

Sources

  1. GitHub Advisory GHSA-58qw-9mgm-455v
  2. NVD CVE-2026-3219
  3. PSF security announcement
  4. Openwall oss-security repost
  5. pip issue #13867
  6. pip pull request #13870
  7. pip changelog 26.1
  8. OSV entry for GHSA-58qw-9mgm-455v
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.