Safeguard
Supply Chain•

Is the hash an index gives pip real protection against tampering?

A hash in an index URL guards against corrupt downloads, not a hostile mirror. Why hash checking needs hashes you store yourself, and how to set them up.

Safeguard Security Team
3 min read

No. A hash that comes from the same index as the file only protects against a corrupted download. If a mirror serves a tampered file, it can serve a matching hash. Real protection needs hashes you store yourself, in your requirements file, so pip can compare downloads with something the mirror cannot change.

What pip says

The pip documentation on secure installs says indexes such as PyPI provide a hash for each distribution in the URL, and pip uses it as protection against download corruption. Because that hash comes from the remote server, it is not a tamper guard. It does not satisfy the demand of hash checking mode, which needs a locally recorded hash on every requirement.

For a team running an internal mirror, this matters. You may assume the checks pip does by default cover a mirror compromise. They do not.

Hash checking mode

Hash checking mode uses hashes stored locally in a requirements file, attached to each requirement. pip describes its purpose as protecting against remote tampering and network issues. Key rules from the docs:

RuleMeaning
All or nothingAdding a hash to any requirement turns the mode on globally
Pin everythingRequirements must be pinned to exact versions, a URL or a path
Cover dependenciesEvery dependency needs a hash, not just top level packages
Partial hashing is an errorOne unhashed requirement could let bad code in

The docs recommend sha256, and they also recommend pairing hashes with a binary only install and installing your own project without its dependencies. A flag also forces the mode on even when no hashes are present, which is useful in deploy scripts to confirm the author supplied them.

How to generate hashes for a small project

pip install pip-tools
pip-compile --generate-hashes requirements.in -o requirements.txt
pip install --require-hashes -r requirements.txt

Generate the file while pointed at a source you trust, ideally upstream through a clean network path, not a mirror you are unsure about. Review the diff when it changes. A package may list several hashes, for example for different platforms, so do not be alarmed by multiple lines.

What hashes do not give you

A hash proves a file matches the one you recorded. It does not tell you the recorded file was safe, who built it, or whether it has known vulnerabilities. If you generate hashes on the day a malicious version is live, you will faithfully pin the malicious version.

So combine the hash file with dependency scanning, and review new versions before they go into the lock.

Where Safeguard fits

Safeguard's SBOM and dependency scanning reports known vulnerabilities in pinned Python packages, which hashes alone cannot do. Try a free scan at gold.safeguard.sh/scan.

Try it yourself

Click through it at your own pace, or open it full screen.

Look at the pinned versions in the inventory and think about which of them you would want hashes for first.

Quick check

Do I need hashes if my mirror requires a login?

A login controls who connects. It does not prove the mirror's cached files are unchanged.

Will hash mode break when I update one package?

You need to regenerate hashes for the new version and its dependencies, then review the diff.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.