GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Agent-mode scan patches the activated VIRTUAL_ENV even when PIPENV_IGNORE_VIRTUALENVS or PIPENV_ACTIVE tells Pipenv to ignore it, leaving the Pipenv venv unpatched with exit 0 · Issue #384 · SocketDev/socket-patch

Agent-mode scan patches the activated VIRTUAL_ENV even when PIPENV_IGNORE_VIRTUALENVS or PIPENV_ACTIVE tells Pipenv to ignore it, leaving the Pipenv venv unpatched with exit 0 #384

New issue
Copy link
New issue
Copy link
Closed
#388
Closed
Agent-mode scan patches the activated VIRTUAL_ENV even when PIPENV_IGNORE_VIRTUALENVS or PIPENV_ACTIVE tells Pipenv to ignore it, leaving the Pipenv venv unpatched with exit 0#384
#388
Copy link
Labels
agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:pipenvPipenvPipenvpriority:p1

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Sep 30, 2026
Issue body actions

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

Summary

find_local_venv_site_packages (crates/socket-patch-core/src/crawlers/python_crawler.rs:276-284) takes VIRTUAL_ENV first and returns as soon as it has a site-packages. Pipenv only uses VIRTUAL_ENV when neither PIPENV_IGNORE_VIRTUALENVS nor PIPENV_ACTIVE is set (pipenv/environments.py: if "PIPENV_ACTIVE" not in os.environ and not self.PIPENV_IGNORE_VIRTUALENVS: self.PIPENV_VIRTUALENV = os.environ.get("VIRTUAL_ENV"), the same on 2018.11.26, 2023.12.1 and 2026.8.0). The crawler ignores both variables:

  • PIPENV_IGNORE_VIRTUALENVS=1 with some other venv activated. This is Pipenv's documented switch for keeping an activated venv from hijacking the project. Pipenv uses $WORKON_HOME/<name>-<hash>, but socket-patch patches the activated venv.
  • PIPENV_ACTIVE=1: you ran pipenv shell in project A, then cd into project B and ran socket-patch there. VIRTUAL_ENV still points at A's venv, and Pipenv in B deliberately ignores it. socket-patch patches project A's venv from project B.

Both cases report added / applied, status: success and exit 0. The venv that pipenv run / pipenv sync use in the project stays unpatched, and an unrelated venv gets modified. In hosted and vendored mode, the stale-install warning (vendor/pypi.rs:611, pipenv_stale_install_warning, which calls the same function) is judged against the wrong venv.

(socket-patch itself sets PIPENV_IGNORE_VIRTUALENVS=1 when it runs pipenv in utils/pipenv.rs:80, so the codebase already relies on this variable meaning "don't use VIRTUAL_ENV".)

This is related to #334 (stray venv/ or .venv shadowing Pipenv's venv), but it's a different trigger and needs a different fix. Pipenv does honour VIRTUAL_ENV by default, so moving Pipenv's placement ahead of ./.venv / ./venv for #334 won't fix it. The VIRTUAL_ENV probe itself has to respect the two Pipenv opt-outs when the project is a Pipenv project.

Impact

Agent mode reports success while the project's real venv keeps the vulnerable bytes, and it writes patched files into a venv the user didn't target (another project's venv, or a tool venv). CI that gates on the exit code passes. PIPENV_IGNORE_VIRTUALENVS=1 is common in shells and CI images that keep a tool venv activated. The pipenv shell → cd flow is everyday developer use.

Repro (Linux; mock patch API or a local manifest)

mkdir proj && cd proj
cat > Pipfile <<'EOF'
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
six = "==1.16.0"
EOF
PIPENV_IGNORE_VIRTUALENVS=1 pipenv install        # -> ~/.local/share/virtualenvs/proj-XXXX
python3 -m venv /tmp/other && /tmp/other/bin/pip install six==1.16.0
export VIRTUAL_ENV=/tmp/other PIPENV_IGNORE_VIRTUALENVS=1   # or: PIPENV_ACTIVE=1 instead of IGNORE
pipenv --venv                                      # ~/.local/share/virtualenvs/proj-XXXX
SOCKET_API_URL=http://127.0.0.1:18080 SOCKET_API_TOKEN=fake SOCKET_ORG_SLUG=test-org \
  socket-patch scan --mode agent --json --yes; echo "exit=$?"
# status: success, patches: [{action: added}], exit=0
pipenv run python -c "import six; print(six.__file__, hasattr(six, 'SOCKET_PATCHED'))"
# ~/.local/share/virtualenvs/proj-XXXX/.../six.py False      <- project venv unpatched
/tmp/other/bin/python -c "import six; print(hasattr(six, 'SOCKET_PATCHED'))"
# True                                                        <- unrelated venv patched

The same thing happens with socket-patch apply --offline against a local .socket/manifest.json (reproduced twice locally on Linux 2023.12.1 and 2026.8.0, and once more per cell in the probe).

Expected vs actual

  • Expected: docs/testing/pipenv-compatibility.md ("Out-of-tree venv naming") says the crawler reproduces Pipenv's placement "so a bare scan/rollback sees the project's venv; before, it fell through to the global interpreter and reported success while the venv stayed unpatched". The project's venv is the one pipenv --venv reports. CLI_CONTRACT.md: status: success / exit 0 means the requested patches are in place.
  • Actual: it patches whichever venv VIRTUAL_ENV names, even when Pipenv has been told to ignore it. It exits 0.

Control: with VIRTUAL_ENV set and neither opt-out set, Pipenv 2023.12.1 / 2026.8.0 also use the activated venv, so socket-patch is correct there (pass).

OS × version

OS Pipenv IGNORE_VIRTUALENVS=1 PIPENV_ACTIVE=1 VIRTUAL_ENV only (control) no VIRTUAL_ENV (control)
Linux 2023.12.1 fail: project venv UNPATCHED, other venv patched, exit 0 fail (same) pass (Pipenv uses it too) pass
Linux 2026.8.0 fail fail pass pass
macOS 2023.12.1 fail fail pass pass
macOS 2026.8.0 fail fail pass pass
Windows 2023.12.1 fail fail pass pass
Windows 2026.8.0 fail fail pass pass
Linux 2018.11.26 (py3.8) fail fail ambiguous (pipenv --venv names VIRTUAL_ENV, but pipenv run imports from the WORKON_HOME venv) pass

First bad version

Not bisected. This isn't a regression: the unconditional VIRTUAL_ENV early return predates Pipenv venv discovery (added in 4.0.0), and neither PIPENV_IGNORE_VIRTUALENVS nor PIPENV_ACTIVE is read anywhere in the crawler.

Suspect code

  • crates/socket-patch-core/src/crawlers/python_crawler.rs:276-284: the unconditional VIRTUAL_ENV early return.
  • crates/socket-patch-core/src/vendor/pypi.rs:611: the stale-install warning goes through the same discovery.

Probe run: https://github.com/SocketDev/socket-patch/actions/runs/36779636041 (6 jobs: ubuntu / macos / windows × 2023.12.1 / 2026.8.0, scan --mode agent against a mock patch API). 2018.11.26 was checked locally on Linux.

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agent
    pm:pipenvPipenvPipenv
    on Sep 30, 2026
  2. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Sep 30, 2026

    pipenv: bug-hunt run 2026-09-30 (#384, #334 comment)

    44df6ad
  3. mikolalysenko commented on Sep 30, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Sep 30, 2026
    CollaboratorAuthor
    More actions

    [agent] Triaged: priority:p1 (Pipenv / PyPI family). Not a duplicate, and no open or merged PR fixes it (the VIRTUAL_ENV probe in find_local_venv_site_packages on main still ignores PIPENV_IGNORE_VIRTUALENVS and PIPENV_ACTIVE).

    Shares root cause with #334: for a Pipenv project, find_local_venv_site_packages (crawlers/python_crawler.rs) runs a generic probe order (VIRTUAL_ENV, ./.venv, ./venv, and only then the $WORKON_HOME venv) instead of resolving the venv the way Pipenv does. Will be fixed together. One Pipenv-specific resolver that follows Pipenv's own order covers both issues: honour VIRTUAL_ENV only without PIPENV_ACTIVE / PIPENV_IGNORE_VIRTUALENVS, honour PIPENV_VENV_IN_PROJECT and [pipenv] venv_in_project, and never use venv/.


    Generated by Claude Code

  4. Mikola Lysenko (mikolalysenko)
    added
    agent:triaged
    priority:p1
    on Sep 30, 2026
  5. mikolalysenko commented on Sep 30, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Sep 30, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue (with #334; shared root cause: Pipenv venv discovery uses a generic probe order instead of Pipenv's own resolution). Branch: agent/fix-pipenv-venv-resolution. Claim-ID: 2026-09-30T22:21:16Z-1947b5


    Generated by Claude Code

  6. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Sep 30, 2026
  7. mikolalysenko commented on Sep 30, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Sep 30, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft fix PR: #388


    Generated by Claude Code

  8. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Sep 30, 2026

    Find the venv Pipenv actually uses

    ee69855
  9. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More actions

    [agent] On main 2463257 (#277, v5) the same discovery bug also causes a false VEX attestation in hosted mode.

    With VIRTUAL_ENV pointing at an unrelated venv (one without six) and PIPENV_IGNORE_VIRTUALENVS=1, Pipenv uses its WORKON_HOME venv. socket-patch looks only at VIRTUAL_ENV, so:

    • scan --mode hosted gives redirected: 1 and no redirect_pypi_stale_install, although Pipenv's venv still holds upstream six. Pipenv won't reinstall a warm venv.
    • socket-patch vex --product pkg:pypi/x@1 emits not_affected / inline_mitigations_already_exist ("Patched via Socket patch … (redirected)"), while pipenv run python -c "import six; print(hasattr(six,'SOCKET_PATCHED'))" prints False.
    • Control (same project, VIRTUAL_ENV unset): the stale warning fires, and vex omits the patch as not_applied.
    Pipenv (Linux, py3.12) control VIRTUAL_ENV=other + PIPENV_IGNORE_VIRTUALENVS=1
    2023.12.1 ✅ ❌ no warning, not_affected
    2026.8.0 ✅ ❌ no warning, not_affected

    I ran each twice. The repro script is the same as the one I just posted on #334 (same root cause, crawlers/python_crawler.rs venv selection).


    Generated by Claude Code

  10. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 1, 2026

    Fix Pipenv venv discovery order (#334, #384) (#388)

    ccd43f5
  11. Mikola Lysenko (mikolalysenko)
    closed this as completedin #388on Oct 1, 2026
  12. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:pipenvPipenvPipenvpriority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.