Insecure SHA1 Hash (cryptography)

MEDIUM

SHA-1 was broken by the SHAttered collision attack in 2017 and is deprecated by NIST for all digital signature uses. Use SHA-256 or SHA-3 instead.

Rule Information

Language
Python
Category
Cryptography
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythoncryptographysha1weak-hashCWE-327OWASP-A02
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset python/PYTHON-CRYPTO-SEC-011 --project .
1
2
3
4
5
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

About This Rule

Understanding the vulnerability and how it is detected

Detects usage of SHA-1 via the `cryptography` library's hazmat primitives interface (`hashes.SHA1()`). SHA-1 produces a 160-bit digest and was formally broken in 2017 when the SHAttered attack (Stevens et al., CWI/Google) produced the first known SHA-1 collision using approximately 6,500 CPU-years of computation. Chosen-prefix collisions, which are more dangerous in practice, were demonstrated in 2020 at lower cost.

NIST deprecated SHA-1 for digital signatures in SP 800-131A and disallowed its use in federal agencies after 2013. Browser vendors removed SHA-1 certificate trust in 2017. Major Certificate Authorities have been prohibited from issuing SHA-1-signed certificates since 2016.

SHA-1 must not be used for digital signatures, TLS certificates, code signing, or any protocol where collision resistance is a security property. It retains limited legacy compatibility use in non-security contexts such as Git object addressing, though even there SHA-256 migration is underway. This rule targets the hazmat layer of the `cryptography` library, indicating intentional low-level cryptographic use.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

2

3

4

How to Fix

Recommended remediation steps

  • 1Replace hashes.SHA1() with hashes.SHA256() for general-purpose hashing and integrity verification.
  • 2Use hashes.SHA3_256() or hashes.SHA3_512() when stronger collision resistance is required or as a hedge against future weaknesses in SHA-2.
  • 3For password hashing, do not use SHA-1 or any raw hash — use Argon2 (argon2-cffi), bcrypt, or scrypt.
  • 4For HMAC-based message authentication, use HMAC with SHA-256 (cryptography.hazmat.primitives.hmac.HMAC with hashes.SHA256()).
  • 5When SHA-1 appears in a legacy protocol or file format you do not control, isolate the usage and layer a SHA-256 HMAC or signature over the output as a compensating control.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

Matches any call to `CryptoHashes.method("SHA1")` where `CryptoHashes` is a QueryType resolving fully-qualified names under `cryptography.hazmat.primitives.hashes`. This catches `hashes.SHA1()` regardless of import aliasing. The rule fires on instantiation of the SHA1 hash object within the cryptography library's hazmat primitives layer, not on the PyCryptodome SHA1 equivalent (see PYTHON-CRYPTO-SEC-015 for that).

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A02:2021 - Cryptographic Failures
PCI DSS v4.0
Requirement 4.2.1 -- use strong cryptography
NIST SP 800-131A
MD5 and SHA-1 disallowed for digital signatures
NIST SP 800-53
SC-13: Cryptographic Protection

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about Insecure SHA1 Hash (cryptography)

SHA-1 is acceptable only for non-security-sensitive legacy compatibility contexts where collision resistance is irrelevant — for example, computing Git-style content hashes for deduplication when an attacker cannot influence the input. It must not be used for digital signatures, TLS certificates, HMAC, or password hashing.
Both are broken for collision resistance. SHA-1 collisions required significantly more computation than MD5 and were demonstrated later (2017 vs 2004). MD5 collisions are now trivially fast; SHA-1 collisions require tens of thousands of CPU-core hours but are within reach of well-resourced attackers. Neither should be used for security.
Git uses SHA-1 as a content-addressable identifier, not as a security primitive — the threat model does not require collision resistance for most Git operations. Git has been migrating to SHA-256 since 2021. This does not make SHA-1 acceptable for security-sensitive applications.
SHA-256 is designed to be fast. An attacker with GPU hardware can compute billions of SHA-256 hashes per second, making brute-force attacks trivial. Use Argon2id, bcrypt, or scrypt, which are specifically designed to be slow and memory-intensive, limiting attack throughput.
Yes, if hashes.SHA1() is passed to an HMAC constructor via the hazmat interface. While HMAC-SHA1 has not been broken in the same way as bare SHA-1, it is deprecated in current standards and should be replaced with HMAC-SHA256.
Run `code-pathfinder scan --ruleset python/cryptography/PYTHON-CRYPTO-SEC-011 --path ./src` in your pipeline. Add `--format sarif` to produce SARIF output compatible with GitHub Advanced Security and similar platforms.
SHAttered (2017) was the first public demonstration of a SHA-1 chosen-prefix collision by Stevens et al. at CWI Amsterdam and Google. They produced two distinct PDF files with identical SHA-1 hashes. The attack required approximately 6,500 CPU-years and 110 GPU-years. In 2020, Leurent and Peyrin demonstrated chosen-prefix SHA-1 collisions at a cost of roughly 900 GPU-years.

New feature

Get these findings posted directly on your GitHub pull requests

The Insecure SHA1 Hash (cryptography) rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works