[agent] Found by the scheduled pip / requirements.txt bug-hunt routine (ledger #309).
Summary
socket-patch setup adds the hook dependency to requirements.txt as a plain appended line, socket-patch[hook] (requirements_add, crates/socket-patch-core/src/setup/pypi/edit.rs:143). It does this without checking whether the file is in pip's hash-checking mode. A requirements.txt produced by pip-compile --generate-hashes, uv pip compile --generate-hashes, poetry export or pipenv requirements --hash has --hash on every requirement. In that mode pip requires every requirement to be ==-pinned and hashed. The appended line is neither, so the next pip install -r requirements.txt fails before installing anything.
setup reports status: success, updated: 1. setup --check then passes too, because it only looks for the hook line.
This is independent of #377 (the hook distribution missing from PyPI): even once socket-patch-hook is published, the unhashed line still breaks every hash-pinned project.
Impact
Running setup on any project that installs from a hashed requirements file breaks installs. That's exactly the security-conscious projects most likely to adopt socket-patch.
Repro
mkdir s && cd s && git init -q
printf 'six==1.16.0 \\\n --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254\n' > requirements.txt
python -m venv v && v/bin/pip install -r requirements.txt # OK
socket-patch setup --yes --json # status success, files: [{kind: pth, path: ./requirements.txt, status: updated}]
cat requirements.txt
# six==1.16.0 \
# --hash=sha256:8abb2f1d…
# socket-patch[hook]
v/bin/pip install -r requirements.txt
# ERROR: In --require-hashes mode, all requirements must have their versions pinned with ==. These do not:
# socket-patch[hook] from https://files.pythonhosted.org/.../socket_patch-4.0.0-...whl (from -r requirements.txt (line 3))
Reproduced twice on main f6b7fb9, and with the released 4.0.0.
Expected vs actual
- Expected: README
setup promises that the hook "can never break interpreter startup" and that setup configures the manifest so a normal install lays down the hook. For a hash-pinned file, setup should either write a pinned and hashed hook line (socket-patch[hook]==<ver> --hash=… for socket-patch and socket-patch-hook), or refuse or warn with a clear message, rather than leave the manifest uninstallable.
- Actual:
status: success, and pip then refuses to install anything from the file.
OS × version
Probe run https://github.com/SocketDev/socket-patch/actions/runs/36771795909 (setup-hashed row):
| OS |
Python 3.8: pip 20.3.4 / 23.3.2 / bundled |
Python 3.13: pip 23.3.2 / bundled 26.2.1 |
| Linux |
fail |
fail |
| macOS |
fail |
fail |
| Windows |
fail |
fail |
Local Linux: pip 24.0 on Python 3.11 and pip 26.2.1 also fail.
First bad release
4.0.0. In 3.3.0, setup doesn't touch requirements.txt (npm only).
Suspect code
crates/socket-patch-core/src/setup/pypi/edit.rs:143-155 (requirements_add): appends HOOK_DEP without looking for --hash / --require-hashes in the file.
- Related, found while testing but not filed separately:
requirements_remove (edit.rs:158) filters by physical line (content.lines()). A hook line written as socket-patch-hook==4.0.0 \ + --hash=… continuation therefore loses only its first line on setup --remove, and a dangling --hash=… line is left behind. pip 24 tolerates this, but it isn't a clean revert.
[agent] Found by the scheduled pip / requirements.txt bug-hunt routine (ledger #309).
Summary
socket-patch setupadds the hook dependency torequirements.txtas a plain appended line,socket-patch[hook](requirements_add,crates/socket-patch-core/src/setup/pypi/edit.rs:143). It does this without checking whether the file is in pip's hash-checking mode. Arequirements.txtproduced bypip-compile --generate-hashes,uv pip compile --generate-hashes,poetry exportorpipenv requirements --hashhas--hashon every requirement. In that mode pip requires every requirement to be==-pinned and hashed. The appended line is neither, so the nextpip install -r requirements.txtfails before installing anything.setupreportsstatus: success, updated: 1.setup --checkthen passes too, because it only looks for the hook line.This is independent of #377 (the hook distribution missing from PyPI): even once
socket-patch-hookis published, the unhashed line still breaks every hash-pinned project.Impact
Running
setupon any project that installs from a hashed requirements file breaks installs. That's exactly the security-conscious projects most likely to adopt socket-patch.Repro
Reproduced twice on main
f6b7fb9, and with the released 4.0.0.Expected vs actual
setuppromises that the hook "can never break interpreter startup" and thatsetupconfigures the manifest so a normal install lays down the hook. For a hash-pinned file,setupshould either write a pinned and hashed hook line (socket-patch[hook]==<ver> --hash=…for socket-patch and socket-patch-hook), or refuse or warn with a clear message, rather than leave the manifest uninstallable.status: success, and pip then refuses to install anything from the file.OS × version
Probe run https://github.com/SocketDev/socket-patch/actions/runs/36771795909 (
setup-hashedrow):Local Linux: pip 24.0 on Python 3.11 and pip 26.2.1 also fail.
First bad release
4.0.0. In 3.3.0,
setupdoesn't touch requirements.txt (npm only).Suspect code
crates/socket-patch-core/src/setup/pypi/edit.rs:143-155(requirements_add): appendsHOOK_DEPwithout looking for--hash/--require-hashesin the file.requirements_remove(edit.rs:158) filters by physical line (content.lines()). A hook line written assocket-patch-hook==4.0.0 \+--hash=…continuation therefore loses only its first line onsetup --remove, and a dangling--hash=…line is left behind. pip 24 tolerates this, but it isn't a clean revert.