Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

With the same release in user site-packages and a system site-packages dir, agent mode patches the shadowed system copy, leaves the copy Python imports unpatched, and VEX attests it (worse since #452: now hits apt-installed packages)

Geschlossen
#501 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
58/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
python, rust
Bereich
cli, security

Rechercherichtung

Start with the Linux reproduction, then read crates/socket-patch-core/src/crawlers/python_crawler.rs:1316 and the well-known-directory scan, followed by crates/socket-patch-cli/src/commands/apply.rs:1861 and :1888-1898. Verify behavior with the scan, apply, vex, and rollback commands from the report. Done means the interpreter-loaded copy is patched, duplicate installs are handled consistently, and VEX does not attest an unpatched loaded copy.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

agent:claimed agent:triaged bug bughunt pm:poetry priority:p1

[agent] Found by the scheduled Poetry bug-hunt routine (ledger #311).

Summary

When one PyPI release (here six==1.16.0) is installed both in the user site (~/.local/lib/python3.X/site-packages, from pip install --user) and in a system site dir (/usr/lib/python3/dist-packages from apt, or /usr/local/lib/python3.X/dist-packages from pip), every global-scope agent run patches the system copy only:

  • scan -g --mode agent, and
  • a plain project scan --mode agent in a Poetry project with virtualenvs.create = false (or any layout where the project venv isn't found and the crawler falls back to the global interpreter, e.g. #476).

Python imports the user-site copy, because sys.path puts user site before the system dirs. That copy stays unpatched. The run reports success, apply re-runs say already_patched, and vex attests not_affected / inline_mitigations_already_exist. On Debian/Ubuntu the write also lands in a dpkg-owned file (/usr/lib/python3/dist-packages/six.py).

Root cause, two parts:

  1. get_global_python_site_packages orders paths as site.getsitepackages() first and site.getusersitepackages() last (crates/socket-patch-core/src/crawlers/python_crawler.rs:1316, plus the well-known-dir scan after it, which also adds ~/.local last). That's the reverse of Python's import precedence.
  2. Apply keeps PyPI on a "one representative" contract and patches only pkg_paths.first() (crates/socket-patch-cli/src/commands/apply.rs:1861 and :1888-1898). The comment there assumes "their crawlers resolve one install dir per version", which doesn't hold in global scope. rollback does fan out to every copy (it reports rolledBack: 1, alreadyOriginal: 1), so the two commands disagree on how many copies exist.

#452 (2035cbb) made this much easier to hit. Before it, apt's .egg-info installs were invisible, so with apt six plus a user-site six the user copy was the only candidate and got patched correctly. Since #452 the apt copy is listed first and wins. With two dist-info copies (/usr/local/.../dist-packages plus user site), the bug already exists in v4.0.0.

Impact

  • A false VEX attestation. The imported copy is still vulnerable, and nothing warns.
  • On Debian/Ubuntu (apt ships six, requests, urllib3, idna, certifi, … as egg-info), -g writes into dpkg-owned files while leaving the copy actually in use unpatched.
  • Poetry users with virtualenvs.create = false (common in Docker images and CI) get the same result from a plain project scan.

Repro (Linux, Debian bookworm image, Python 3.11, Poetry 2.5.1)

The mock patch API serves one agent patch for pkg:pypi/[email protected] that appends SOCKET_PATCHED = 1 to six.py. It uses the same routes as tests/vex_pypi_real_common/mod.rs, plus /patches/blob/<hash>. $A = --api-url http://127.0.0.1:18080 --api-token fake --org test-org --patch-server-url http://127.0.0.1:18080.

# apt's python3-six 1.16.0 egg-info is in /usr/lib/python3/dist-packages
python3 -m pip install --user --ignore-installed --break-system-packages six==1.16.0
python3 -c 'import six; print(six.__file__)'   # -> /root/.local/lib/python3.11/site-packages/six.py

mkdir nc && cd nc
cat > pyproject.toml <<'EOF'
[tool.poetry]
name = "demo"
version = "0.1.0"
description = ""
authors = ["x <x@x>"]
package-mode = false
[tool.poetry.dependencies]
python = "^3.11"
six = "1.16.0"
EOF
printf '[virtualenvs]\ncreate = false\n' > poetry.toml
poetry lock && poetry install           # "No dependencies to install or update"
poetry run python -c 'import six; print(six.__file__)'   # user-site copy

socket-patch scan --mode agent --yes $A      # success (same with: mkdir g && cd g && socket-patch scan -g --mode agent --yes $A)
grep -c SOCKET_PATCHED /usr/lib/python3/dist-packages/six.py               # 1  <- shadowed copy patched
grep -c SOCKET_PATCHED ~/.local/lib/python3.11/site-packages/six.py        # 0  <- imported copy unpatched
python3 -c 'import six; print(hasattr(six, "SOCKET_PATCHED"))'           # False
socket-patch apply --json $A               # skipped / already_patched
socket-patch vex --product pkg:pypi/[email protected] --json --output v.json $A   # not_affected / inline_mitigations_already_exist
socket-patch rollback --json $A            # rolledBack: 1, alreadyOriginal: 1 (it sees both copies)

It reproduces 2/2 for each of: scan -g --mode agent, vex -g, and the Poetry create = false project scan.

Expected vs actual

  • Expected: agent mode patches the copy the interpreter loads, or every installed copy as gem/npm do (apply.rs comment: "leaving the other store pristine is a silent false 'applied'"). VEX only attests when the loaded copy is patched. CLI_CONTRACT.md's VEX rule is that a statement is emitted only for a patch that is actually applied.
  • Actual: the shadowed copy is patched, the loaded copy isn't, and VEX attests anyway.

OS × version

OS Copies present Binary Result
Linux apt egg-info + user site main 61cfb9b, 2035cbb (#452) fail: apt copy patched
Linux apt egg-info + user site v4.0.0, 2035cbb^ pass: user copy patched
Linux /usr/local/.../dist-packages dist-info + user site main, 2035cbb^, v4.0.0 fail: /usr/local copy patched
Linux /usr/local/.../dist-packages only main pass
macOS / Windows — — untested (probe branches blocked). macOS user site (~/Library/Python/3.X/lib/python/site-packages) has the same ordering, so it's likely affected.

Poetry versions: 2.5.1 (create = false, user-site copy kept). With create = false, Poetry 1.8.5 / 2.0.1 / 2.2.1 in this image reinstalled six into /usr/local/lib/python3.11/dist-packages, which precedes apt on sys.path, so those didn't reproduce until a user-site copy was re-added. The -g path doesn't depend on the Poetry version.

First bad commit

For the apt + user-site case: 2035cbb ("Fix Python crawler missing .egg-info installs (#447) (#452)"), bisected with release builds of 2035cbb^ and 2035cbb, 2/2 each. For two dist-info copies, it never worked (v4.0.0 fails).

Suspect code

  • crates/socket-patch-core/src/crawlers/python_crawler.rs:1316 (user site printed last) and the well-known-dir order right after it.
  • crates/socket-patch-cli/src/commands/apply.rs:1861, :1888-1898 (PyPI patches only pkg_paths.first()).
  • Related but distinct: #409 (--system-site-packages venv, hosted), #476 (Poetry venv not found, so this fallback is reached).
Vorherrschende Sprache
Rust
Sterne
8
Forks
0
Ø Merge
19 Std. 21 Min.
Gemergte PRs (30 T.)
421

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus SocketDev/socket-patch

Alle Issues in SocketDev/socket-patch

Ähnliche Issues

Weitere Issues zu Rust

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.