Skip to content

Verify wheel RECORD file hashes during installation (PEP 427)#13816

Open
Ashutosh0x wants to merge 1 commit intopypa:mainfrom
Ashutosh0x:fix/record-hash-verification-4705
Open

Verify wheel RECORD file hashes during installation (PEP 427)#13816
Ashutosh0x wants to merge 1 commit intopypa:mainfrom
Ashutosh0x:fix/record-hash-verification-4705

Conversation

@Ashutosh0x
Copy link
Copy Markdown

@Ashutosh0x Ashutosh0x commented Feb 20, 2026

Summary

pip now verifies each extracted file's sha256 hash against the wheel's RECORD file during installation. If a mismatch is detected, the install fails with a clear error message.

Fixes #4705 pip silently installed tampered wheels without checking RECORD hashes.

Changes

  • Parse RECORD hashes before file extraction in _install_wheel()
  • After each file is saved, compute its sha256 and compare against RECORD
  • Skip files with empty hashes (RECORD itself, per PEP 427 spec)
  • Reuse distribution object to avoid duplicate wheel parsing
  • Add tests for tampered and valid wheel scenarios
  • Add news entry

Test Plan

  • est_tampered_wheel_raises_error: Creates a valid wheel, modifies a file in the zip without updating RECORD, verifies InstallationError is raised
  • est_valid_wheel_installs_successfully: Creates and installs a normal wheel, verifies success

Security Impact

This closes a 7+ year old security gap (filed Sep 2017) where an attacker who could intercept or modify a wheel file on a mirror/CDN could inject malicious code that pip would silently install.

pip now checks each extracted file's sha256 hash against the wheel's
RECORD file during installation. If a hash mismatch is detected, the
install fails with a clear error message indicating the wheel may be
corrupted or tampered with.

This closes a long-standing security gap where pip would silently
install wheels with modified files (e.g. tampered .so/.pyd libraries)
even when the RECORD file contained valid checksums.

Key changes:
- Parse RECORD hashes before file extraction (moved earlier)
- Verify each file's hash after save, skip files with empty hashes
  (RECORD itself, per PEP 427 spec)
- Reuse distribution object to avoid duplicate wheel parsing
- Add tests for tampered and valid wheel scenarios

Fixes pypa#4705
@notatallshaw
Copy link
Copy Markdown
Member

Security Impact

This closes a 7+ year old security gap (filed Sep 2017) where an attacker who could intercept or modify a wheel file on a mirror/CDN could inject malicious code that pip would silently install.

This isn't a security issue, do not discuss it in such terms, if an attacker can intercept and modify the wheel then they can modify the RECORD file.

Further, your PR does not match the standards that would be required of a security PR, if the algo listed isn't sha256 then it simply doesn't verify the record, were this a security feature that would be an obvious gap. You should read the specification before attempting such a PR to make sure it is complaint with them: https://packaging.python.org/en/latest/specifications/recording-installed-packages/#the-record-file

In general we're probably not going to accept this PR for the reasons I outline in #4705 (comment), but I'm also concerned about the performance impact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pip does not check hashes in wheel RECORD contents during installation

2 participants