[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).
Summary
When a hosted (redirect_pypi_stale_install) or vendored (pypi_pipenv_stale_install) scan finds a warm Pipenv venv that still holds the upstream release, the warning prints the remedy pipenv run pip uninstall -y <name> && pipenv sync (or pipenv --rm && pipenv sync). The remedy text doesn't depend on the Pipfile.lock category of the redirected entry. Plain pipenv sync installs only default. So when the patched package is pinned in develop ([dev-packages]) or a Pipenv 2022+ named category (e.g. [docs]), following the printed remedy removes the package from the venv, and doesn't reinstall it patched. The --rm variant also drops every other dev / category package.
Impact
- A user who follows the CLI's own remedy ends up with the dev / category package missing (
ModuleNotFoundError), not patched. Their test or docs tooling breaks, and the patch still isn't installed.
- The same commands are listed as "Verified remedies" in
docs/testing/pipenv-compatibility.md:47, but they only verify for default.
socket-patch vex --product … then attests not_affected (inline_mitigations_already_exist) from the lock alone, so nothing tells the user the remedy didn't work.
Repro (Linux, real Pipenv; patch data from a local mock patch API serving a patched six 1.16.0 wheel)
mkdir p && cd p
cat > Pipfile <<'EOF'
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
[dev-packages]
six = "==1.16.0"
EOF
pipenv lock && pipenv sync --dev # warm venv holds upstream six
socket-patch scan --mode hosted --yes # or --mode vendored
# warning: "... Reinstall it from the lock without touching the Pipfile:
# `pipenv run pip uninstall -y six && pipenv sync` ..., or `pipenv --rm && pipenv sync` ..."
pipenv run pip uninstall -y six && pipenv sync # the printed remedy, verbatim
pipenv run python -c "import six"
# ModuleNotFoundError: No module named 'six'
socket-patch vex --product pkg:pypi/app@0.1.0 -O vex.json # not_affected, inline_mitigations_already_exist
pipenv sync --dev && pipenv run python -c "import six; print(six.SOCKET_PATCHED)" # the working remedy -> patched
For a [docs] category the working remedy is pipenv sync --categories docs.
Expected vs actual
- Expected: the warning's remedy reinstalls the patched release from the lock (its own wording is "Reinstall it from the lock"). Per pipenv-compatibility.md, every category is redirected, so the remedy should name the category:
pipenv sync --dev for develop, pipenv sync --categories <name> for a named category (and pipenv install --deploy --dev on pre-2018), or list them all for --rm.
- Actual: the remedy is the same for every category. For
develop / named categories it uninstalls the package and leaves it uninstalled (exit 0).
Matrix (each cell run with both printed remedies, uninstall && sync and --rm && sync, on 045d7ec)
| OS |
Pipenv |
category |
hosted |
vendored |
| Linux |
2018.11.26 (py3.8) |
default |
pass (patched) |
pass |
| Linux |
2018.11.26 |
develop |
fail (six missing) |
fail |
| Linux |
2022.12.19 (py3.11) |
default |
pass |
pass |
| Linux |
2022.12.19 |
develop / docs |
fail / fail |
fail / fail |
| Linux |
2023.12.1 |
default |
pass |
pass |
| Linux |
2023.12.1 |
develop / docs |
fail / fail |
fail / fail |
| Linux |
2026.8.0 |
default |
pass |
pass |
| Linux |
2026.8.0 |
develop / docs |
fail / fail |
fail / fail |
Control: pipenv sync --dev / pipenv sync --categories docs after the uninstall gives the patched wheel on 2018 / 2026. macOS / Windows weren't probed (the remedy text doesn't depend on the platform).
Suspect code
- Hosted:
crates/socket-patch-cli/src/commands/scan/hosted/python.rs:116-122. The remedy format! uses only {name}, not the lock category the redirect rewrote.
- Vendored:
crates/socket-patch-core/src/vendor/pypi.rs:663, the same fixed text.
- Docs:
docs/testing/pipenv-compatibility.md:47 ("Verified remedies").
First bad: present since the remedy text was added (v5 hosted / vendored Pipenv); not bisected further.
[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).
Summary
When a hosted (
redirect_pypi_stale_install) or vendored (pypi_pipenv_stale_install) scan finds a warm Pipenv venv that still holds the upstream release, the warning prints the remedypipenv run pip uninstall -y <name> && pipenv sync(orpipenv --rm && pipenv sync). The remedy text doesn't depend on the Pipfile.lock category of the redirected entry. Plainpipenv syncinstalls onlydefault. So when the patched package is pinned indevelop([dev-packages]) or a Pipenv 2022+ named category (e.g.[docs]), following the printed remedy removes the package from the venv, and doesn't reinstall it patched. The--rmvariant also drops every other dev / category package.Impact
ModuleNotFoundError), not patched. Their test or docs tooling breaks, and the patch still isn't installed.docs/testing/pipenv-compatibility.md:47, but they only verify fordefault.socket-patch vex --product …then attestsnot_affected(inline_mitigations_already_exist) from the lock alone, so nothing tells the user the remedy didn't work.Repro (Linux, real Pipenv; patch data from a local mock patch API serving a patched
six 1.16.0wheel)For a
[docs]category the working remedy ispipenv sync --categories docs.Expected vs actual
pipenv sync --devfordevelop,pipenv sync --categories <name>for a named category (andpipenv install --deploy --devon pre-2018), or list them all for--rm.develop/ named categories it uninstalls the package and leaves it uninstalled (exit 0).Matrix (each cell run with both printed remedies,
uninstall && syncand--rm && sync, on045d7ec)Control:
pipenv sync --dev/pipenv sync --categories docsafter the uninstall gives the patched wheel on 2018 / 2026. macOS / Windows weren't probed (the remedy text doesn't depend on the platform).Suspect code
crates/socket-patch-cli/src/commands/scan/hosted/python.rs:116-122. The remedyformat!uses only{name}, not the lock category the redirect rewrote.crates/socket-patch-core/src/vendor/pypi.rs:663, the same fixed text.docs/testing/pipenv-compatibility.md:47("Verified remedies").First bad: present since the remedy text was added (v5 hosted / vendored Pipenv); not bisected further.