# Risk map — pypa/virtualenv

> Canonical page: https://codevetter.com/unpack/virtualenv/risk-map

# Risk map — pypa/virtualenv

Scanned commit 571bc2041dae5ecbd250d82ec7ef482cfd3c3b69 (2026-10-02). Generated by codevetter codevetter 1.15.0 on 2026-10-02.

Source inspection; upstream code and tests were not executed.

These are source observations and explicitly labeled hypotheses, not confirmed vulnerabilities. The important boundaries involve executing trusted interpreters/plugins, downloading executable packages, generating shell/configuration text, and deleting or overwriting filesystem state. Controls include strict download arguments, digest checks, extraction containment, and quoted substitutions. Cache reuse and subprocess environment handling deserve focused review because their behavior spans multiple invocations and processes.
- Registered entry points are loaded through e.load before implementation selection; the threat model explicitly trusts installed plugins and target interpreters running with the invoking user's rights. — [src/virtualenv/run/plugin/base.py#L20-L36](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/run/plugin/base.py#L20-L36) [.github/THREAT_MODEL.md#L48-L67](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/.github/THREAT_MODEL.md#L48-L67) [src/virtualenv/create/via_global_ref/venv.py#L72-L86](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/via_global_ref/venv.py#L72-L86)
- Filesystem effects extend beyond repository scope: --clear deletes the validated destination, --reset-app-data deletes the selected cache, default cache setup can migrate an old folder, and creation may write an adjacent .venv redirect. — [src/virtualenv/create/creator.py#L217-L227](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/creator.py#L217-L227) [src/virtualenv/create/creator.py#L270-L288](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/create/creator.py#L270-L288) [src/virtualenv/app_data/via_disk_folder.py#L65-L67](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/app_data/via_disk_folder.py#L65-L67) [src/virtualenv/app_data/__init__.py#L32-L46](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/app_data/__init__.py#L32-L46)
- Download arguments are allow-listed, but PyPI digest verification is skipped when PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, or PIP_INDEX is nonempty; the heuristic explicitly does not inspect pip.conf, and local extra-search wheels are trusted without hashes. — [src/virtualenv/seed/wheels/acquire.py#L23-L34](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/acquire.py#L23-L34) [src/virtualenv/seed/wheels/acquire.py#L138-L173](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/acquire.py#L138-L173) [src/virtualenv/seed/wheels/acquire.py#L220-L231](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/acquire.py#L220-L231) [.github/THREAT_MODEL.md#L68-L77](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/.github/THREAT_MODEL.md#L68-L77)
- VIRTUALENV_PERIODIC_UPDATE_INSECURE enables an unverified TLS context after the normal metadata lookup fails; those metadata responses provide the expected downloaded-wheel SHA-256 and release dates. — [src/virtualenv/seed/wheels/periodic_update.py#L360-L368](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/periodic_update.py#L360-L368) [src/virtualenv/seed/wheels/periodic_update.py#L379-L420](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/periodic_update.py#L379-L420) [src/virtualenv/seed/wheels/periodic_update.py#L423-L465](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/periodic_update.py#L423-L465)
- Downloaded wheels and installation images are reused from trusted app-data without re-verification; bundled verification is memoized by filename, and has_image accepts any nonempty image directory. — [.github/THREAT_MODEL.md#L62-L65](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/.github/THREAT_MODEL.md#L62-L65) [src/virtualenv/seed/wheels/embed/__init__.py#L96-L108](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/embed/__init__.py#L96-L108) [src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L219-L220](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L219-L220) [src/virtualenv/seed/embed/via_app_data/via_app_data.py#L156-L159](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/via_app_data/via_app_data.py#L156-L159)
- PipInvoke debug logging formats the full subprocess environment through LogCmd; trigger_update launches without its supplied env mapping, and _run_do_update uses os.environ rather than that caller mapping. — [src/virtualenv/seed/embed/pip_invoke.py#L30-L37](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/pip_invoke.py#L30-L37) [src/virtualenv/util/subprocess/__init__.py#L13-L22](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/util/subprocess/__init__.py#L13-L22) [src/virtualenv/seed/wheels/periodic_update.py#L252-L257](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/periodic_update.py#L252-L257) [src/virtualenv/seed/wheels/periodic_update.py#L329-L337](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/periodic_update.py#L329-L337)
- Hypothesis: an interrupted image build or concurrent update-log writer can leave partial/shared state because image validity is only nonemptiness, JSON writes replace contents directly, and inspected update callers do not enter the store's available lock context. (inferred) — [src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L71-L89](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L71-L89) [src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L219-L220](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L219-L220) [src/virtualenv/app_data/via_disk_folder.py#L150-L158](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/app_data/via_disk_folder.py#L150-L158) [src/virtualenv/seed/wheels/periodic_update.py#L88-L107](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/wheels/periodic_update.py#L88-L107)
- Hypothesis: attacker-modified existing distribution metadata could expand reseeding's deletion scope, since _uninstall_dist joins top_level.txt and RECORD paths to dist.parent and deletes them without an explicit containment check in this function; the documented model trusts destination files. (inferred) — [src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L187-L213](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/src/virtualenv/seed/embed/via_app_data/pip_install/base.py#L187-L213) [.github/THREAT_MODEL.md#L58-L65](https://github.com/pypa/virtualenv/blob/571bc2041dae5ecbd250d82ec7ef482cfd3c3b69/.github/THREAT_MODEL.md#L58-L65)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
