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
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
[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).
Summary
Since #388 (ccd43f5), find_local_venv_site_packages returns early for any directory with a Pipfile or Pipfile.lock. It returns only the venv Pipenv itself would resolve, and never ./venv or an in-project .venv that Pipenv's settings rule out. The code comment there says: "When Pipenv has no venv yet there is nothing to patch, so the generic probes must not fall back to a tree Pipenv will never use."
But when that returns nothing, get_site_packages_paths (crates/socket-patch-core/src/crawlers/python_crawler.rs:1719-1724) sees is_python_project(cwd) and falls back to get_global_python_site_packages(). So an agent-mode scan --apply (no -g) in such a project:
ignores the project's venv/, which is the environment the repo actually runs in (a Pipfile kept for dev while Docker/CI use python -m venv venv && pip install -r requirements.txt), and patched it before Fix Pipenv venv discovery order (#334, #384) #388;
patches the system interpreter in place (/usr/lib/python3/dist-packages/six.py on Debian/Ubuntu), and records it in .socket/manifest.json;
exits 0 with applied: 1, and vex --product … then attests not_affected while the project's venv still holds the vulnerable bytes.
The same fallback fires for an in-project .venv with PIPENV_VENV_IN_PROJECT=0 and no WORKON_HOME venv. There, skipping .venv is correct (#334), but falling through to the system Python isn't. It also fires for a fresh Pipenv checkout before pipenv install. #447 (2035cbb, egg-info discovery) widens the blast radius: apt-installed Debian packages such as python3-six are .egg-info installs and are now found and patched.
As a non-root user, the scan instead fails with Permission denied (os error 13) on the system path (exit 1), and the project's venv/ is still never patched.
Impact
A project-scoped command (no -g) modifies files outside the project, in the OS Python, as root in Docker builds. rollback does restore them, but nobody expects a project scan to touch them.
The environment the app actually runs in stays vulnerable, and both the exit code and VEX say it's fixed.
Before Fix Pipenv venv discovery order (#334, #384) #388, the same project patched venv/ correctly, so this is a regression for any repo with a Pipfile (or a leftover Pipfile.lock) and a plain venv/.
Repro (Linux, Debian/Ubuntu Python with python3-six 1.16.0 installed; mock patch API serving six 1.16.0)
(The mock's patched six.py appends SOCKET_PATCHED = True.)
Expected vs actual
Expected: CLI_CONTRACT.md ("cwd-only (single project)", line ~479) says "The crawler inspects only the project rooted at --cwd (pypi looks at $VIRTUAL_ENV, <cwd>/.venv / venv, then a Poetry project's out-of-tree virtualenv(s)…)". Global packages are the -g / --global-prefix surface. The Fix Pipenv venv discovery order (#334, #384) #388 comment itself says a Pipenv project with no Pipenv venv has "nothing to patch". So either the project's venv/ is patched, as before Fix Pipenv venv discovery order (#334, #384) #388, or nothing is patched and the scan says so. The system site-packages must never be patched without -g. Which of the two applies to venv/ is a maintainer call. The global write is the defect either way.
Actual: the system Python is patched (as root) or the run fails on it (non-root), and the project's venv is never considered.
Cells (Linux; macOS/Windows probes blocked this run, see the ledger)
Pipfile + lock with the Pipenv WORKON_HOME venv present (control)
✅ untouched
✅ Pipenv venv patched
0
—
Each main cell was reproduced twice (scan → rollback → scan).
First bad:ccd43f5 (#388) for the venv/ and .venv shapes, where bae5d3a is good. The global fallback itself is older. #447 (2035cbb) makes egg-info system packages visible to it.
Suspect code
crates/socket-patch-core/src/crawlers/python_crawler.rs:362-364: if pipenv { return pipenv_project_site_packages(cwd, var).await; }. An empty result here means "nothing to patch", but the caller can't tell that apart from "no venv probed".
crates/socket-patch-core/src/crawlers/python_crawler.rs:1719-1724: the is_python_project → get_global_python_site_packages() fallback in non-global mode.
[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).
Summary
Since #388 (
ccd43f5),find_local_venv_site_packagesreturns early for any directory with aPipfileorPipfile.lock. It returns only the venv Pipenv itself would resolve, and never./venvor an in-project.venvthat Pipenv's settings rule out. The code comment there says: "When Pipenv has no venv yet there is nothing to patch, so the generic probes must not fall back to a tree Pipenv will never use."But when that returns nothing,
get_site_packages_paths(crates/socket-patch-core/src/crawlers/python_crawler.rs:1719-1724) seesis_python_project(cwd)and falls back toget_global_python_site_packages(). So an agent-modescan --apply(no-g) in such a project:venv/, which is the environment the repo actually runs in (a Pipfile kept for dev while Docker/CI usepython -m venv venv && pip install -r requirements.txt), and patched it before Fix Pipenv venv discovery order (#334, #384) #388;/usr/lib/python3/dist-packages/six.pyon Debian/Ubuntu), and records it in.socket/manifest.json;applied: 1, andvex --product …then attestsnot_affectedwhile the project's venv still holds the vulnerable bytes.The same fallback fires for an in-project
.venvwithPIPENV_VENV_IN_PROJECT=0and no WORKON_HOME venv. There, skipping.venvis correct (#334), but falling through to the system Python isn't. It also fires for a fresh Pipenv checkout beforepipenv install. #447 (2035cbb, egg-info discovery) widens the blast radius: apt-installed Debian packages such aspython3-sixare.egg-infoinstalls and are now found and patched.As a non-root user, the scan instead fails with
Permission denied (os error 13)on the system path (exit 1), and the project'svenv/is still never patched.Impact
-g) modifies files outside the project, in the OS Python, as root in Docker builds.rollbackdoes restore them, but nobody expects a project scan to touch them.venv/correctly, so this is a regression for any repo with a Pipfile (or a leftover Pipfile.lock) and a plainvenv/.Repro (Linux, Debian/Ubuntu Python with
python3-six1.16.0 installed; mock patch API servingsix 1.16.0)(The mock's patched
six.pyappendsSOCKET_PATCHED = True.)Expected vs actual
--cwd(pypi looks at$VIRTUAL_ENV,<cwd>/.venv/venv, then a Poetry project's out-of-tree virtualenv(s)…)". Global packages are the-g/--global-prefixsurface. The Fix Pipenv venv discovery order (#334, #384) #388 comment itself says a Pipenv project with no Pipenv venv has "nothing to patch". So either the project'svenv/is patched, as before Fix Pipenv venv discovery order (#334, #384) #388, or nothing is patched and the scan says so. The system site-packages must never be patched without-g. Which of the two applies tovenv/is a maintainer call. The global write is the defect either way.Cells (Linux; macOS/Windows probes blocked this run, see the ledger)
61cfb9b)bae5d3a(pre-#388)venv/, no Pipenv venv (root)venv/patched, system untouched (2/2)Permission denied.venv,PIPENV_VENV_IN_PROJECT=0, no WORKON venv.venvnot patched (correct per #334).venv(the #334 bug)Each main cell was reproduced twice (scan → rollback → scan).
First bad:
ccd43f5(#388) for thevenv/and.venvshapes, wherebae5d3ais good. The global fallback itself is older. #447 (2035cbb) makes egg-info system packages visible to it.Suspect code
crates/socket-patch-core/src/crawlers/python_crawler.rs:362-364:if pipenv { return pipenv_project_site_packages(cwd, var).await; }. An empty result here means "nothing to patch", but the caller can't tell that apart from "no venv probed".crates/socket-patch-core/src/crawlers/python_crawler.rs:1719-1724: theis_python_project→get_global_python_site_packages()fallback in non-global mode.