You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Agent mode honours the Pipfile's [pipenv] venv_in_project = true for every Pipenv, but only 2026.2+ read it, so on Pipenv 2018–2026.1 the WORKON_HOME venv stays unpatched, the system Python is patched instead, and VEX attests not_affected #842
[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).
Summary
pipenv_venv_in_project (crates/socket-patch-core/src/crawlers/python_crawler.rs:668) reads the Pipfile's [pipenv] venv_in_project key for every Pipenv project. If the key is true and ./.venv doesn't exist, pipenv_project_site_packages returns no venv at all (python_crawler.rs:711, "An explicit 'in project' with no ./.venv means Pipenv has no venv yet").
That holds only for Pipenv 2026.2.0+, the first release that reads the key (Project._pipfile_venv_in_project). Pipenv 2018.11.26 through 2026.1.0 ignore it and put the venv at $WORKON_HOME/<name>-<hash> as usual. So when a team commits venv_in_project = true and a developer, CI image or distro still runs Pipenv ≤ 2026.1, the real venv is never found:
vex then attests not_affected for the project, even though pipenv run imports the unpatched bytes.
This is the mirror image of the venv_in_project = false case, which PR #654 already treats as "only 2026.2+ reads it". The = true case with no ./.venv is unchanged in #654 (its test only covers = true with a ./.venv present, which is correct for every version). I re-ran the repro on the #654 head d8356ae and it still fails.
Impact
A silent miss with a false attestation, plus an unrequested write into the system interpreter. A team that adopts the documented Pipenv 2026.2 setting gets wrong results on every older Pipenv in its fleet.
Repro (Linux, real Pipenv)
export WORKON_HOME=/tmp/wh PIPENV_YES=1
mkdir proj &&cd proj
printf'[[source]]\nurl = "https://pypi.org/simple"\nverify_ssl = true\nname = "pypi"\n\n[packages]\nsix = "==1.16.0"\n\n[pipenv]\nvenv_in_project = true\n'> Pipfile
pipenv install # Pipenv 2025.1.3: venv at $WORKON_HOME/proj-<hash>, no ./.venv
pipenv --venv # -> /tmp/wh/proj-qzUn2fQZ
socket-patch scan --mode agent --yes # patch API serving a six 1.16.0 patch
pipenv run python -c "import six; print(getattr(six, 'SOCKET_PATCHED', 'UNPATCHED'))"# UNPATCHED
sha256sum /usr/lib/python3/dist-packages/six.py # changed: the system copy was patched
socket-patch vex --product pkg:pypi/demo@1.0.0 --output vex.json # statement: not_affected
Patch data came from a local mock patch API (batch / by-package / view / blob) serving a six 1.16.0 patch that appends SOCKET_PATCHED = True. socket-patch rollback --yes restored the system six.py byte-identically.
macOS and Windows weren't probed (probe branches are blocked, see the ledger). The code path doesn't depend on the OS.
First bad commit
The Pipfile key was first read in ccd43f5 (#388, "Fix Pipenv venv discovery order"), according to git log -S venv_in_project. I didn't build its parent for this shape.
Suspect code
crates/socket-patch-core/src/crawlers/python_crawler.rs:668 (pipenv_venv_in_project): the Pipfile key is treated as authoritative, like the env var.
crates/socket-patch-core/src/crawlers/python_crawler.rs:711: in_project == Some(true) && !dot_venv.exists() returns no venv.
The hosted stale-install warning (crates/socket-patch-cli/src/commands/scan/hosted/python.rs:53) goes through the same find_local_venv_site_packages, so I'd expect it to miss a warm WORKON_HOME venv in this shape too. I haven't verified that in this run.
Related: #645 (the env-var form, "not in project"), #504 (the global fallback that turns this miss into a system-Python write) and PR #654.
[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).
Summary
pipenv_venv_in_project(crates/socket-patch-core/src/crawlers/python_crawler.rs:668) reads the Pipfile's[pipenv] venv_in_projectkey for every Pipenv project. If the key is true and./.venvdoesn't exist,pipenv_project_site_packagesreturns no venv at all (python_crawler.rs:711, "An explicit 'in project' with no./.venvmeans Pipenv has no venv yet").That holds only for Pipenv 2026.2.0+, the first release that reads the key (
Project._pipfile_venv_in_project). Pipenv 2018.11.26 through 2026.1.0 ignore it and put the venv at$WORKON_HOME/<name>-<hash>as usual. So when a team commitsvenv_in_project = trueand a developer, CI image or distro still runs Pipenv ≤ 2026.1, the real venv is never found:scanfalls through to the global-interpreter fallback and patches the system Python's site-packages in place (the Agent-mode scan in a Pipenv project without a Pipenv venv patches the system Python's site-packages in place instead of the project's venv/ (regression from #388) #504 path). The project's venv stays unpatched, and the exit code is 0 with "1 of 1 targeted patch applied".vexthen attestsnot_affectedfor the project, even thoughpipenv runimports the unpatched bytes.This is the mirror image of the
venv_in_project = falsecase, which PR #654 already treats as "only 2026.2+ reads it". The= truecase with no./.venvis unchanged in #654 (its test only covers= truewith a./.venvpresent, which is correct for every version). I re-ran the repro on the #654 headd8356aeand it still fails.Impact
A silent miss with a false attestation, plus an unrequested write into the system interpreter. A team that adopts the documented Pipenv 2026.2 setting gets wrong results on every older Pipenv in its fleet.
Repro (Linux, real Pipenv)
Patch data came from a local mock patch API (batch / by-package / view / blob) serving a six 1.16.0 patch that appends
SOCKET_PATCHED = True.socket-patch rollback --yesrestored the systemsix.pybyte-identically.Expected vs actual
.venvsubject toPIPENV_VENV_IN_PROJECTand the Pipfile's[pipenv] venv_in_project, or Pipenv's default$WORKON_HOME/<dir>-<hash>[-<python>]". The installed Pipenv version can't be known without running it, so the safe reading is the one Agent mode patches only the WORKON_HOME venv when a Pipenv project also has an auto-detected ./.venv, so Pipenv 2018–2026.1 keep running the unpatched .venv and VEX attests not_affected (regression from #388) #529 / PR Fix Pipenv venv discovery settings view (#645, #546) #654 use elsewhere: withvenv_in_project = trueand no./.venv, also look up the WORKON_HOME venv. A pre-2026.2 Pipenv uses it; 2026.2+ has no venv yet, so there's nothing extra to patch. Only an explicit env var (PIPENV_VENV_IN_PROJECT=1, honoured by every release) justifies "no venv yet".not_affected.Matrix (Linux, main
045d7ec, 2/2 runs each)pipenv runsix after scan$WORKON_HOME/proj-…$WORKON_HOME/proj-…venv_in_project = "yes"$WORKON_HOME/proj-…$WORKON_HOME/proj-…$WORKON_HOME/proj-…./.venv[pipenv]key (control)$WORKON_HOME/proj-…d8356ae, 2023.12.1 / 2025.1.3$WORKON_HOME/proj-…macOS and Windows weren't probed (probe branches are blocked, see the ledger). The code path doesn't depend on the OS.
First bad commit
The Pipfile key was first read in
ccd43f5(#388, "Fix Pipenv venv discovery order"), according togit log -S venv_in_project. I didn't build its parent for this shape.Suspect code
crates/socket-patch-core/src/crawlers/python_crawler.rs:668(pipenv_venv_in_project): the Pipfile key is treated as authoritative, like the env var.crates/socket-patch-core/src/crawlers/python_crawler.rs:711:in_project == Some(true) && !dot_venv.exists()returns no venv.crates/socket-patch-cli/src/commands/scan/hosted/python.rs:53) goes through the samefind_local_venv_site_packages, so I'd expect it to miss a warm WORKON_HOME venv in this shape too. I haven't verified that in this run.Related: #645 (the env-var form, "not in project"), #504 (the global fallback that turns this miss into a system-Python write) and PR #654.