GHSA-crqm-m339-7m2p
MEDIUMGHSA-crqm-m339-7m2p is a medium-severity (CVSS 6.2) CWE-480 vulnerability in pyzipper. O3 Security confirms whether GHSA-crqm-m339-7m2p is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.
pyzipper has an encryption bypass for small files encrypted using it
Exploitation Status
No confirmed exploitation observed yet
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for GHSA-crqm-m339-7m2p.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-crqm-m339-7m2p plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 358,265 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
pyzipperReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Impact
A Python operator precedence bug in pyzipper/zipfile_aes.py caused the AE-2 format to never be automatically selected during encryption, regardless of file size or compression type. As a result, all encrypted entries are written in AE-1 format unless AE-2 is explicitly forced by the caller. AE-1 stores the plaintext CRC32 checksum unencrypted in the ZIP header. During investigation of this issue, it was also found that when writing to an unseekable zip archive, the CRC32 value was always written to the datadescripter section.
The AES encryption itself is not broken. An attacker who possesses the archive can read the CRC32 from the header without decrypting anything, then brute-force candidate plaintexts by computing CRC32(candidate) and comparing against the stored value. In practice, this attack is feasible today only against small or low-entropy files, as CRC32 exhaustion across a large plaintext space is computationally prohibitive on current hardware. Files with high-entropy or large content are not practically at risk under current computing constraints. Without this bug, pyzipper would have removed the CRC32 value for any file with content of less than 20 bytes uncompressed.
Patches
Upgrade to pyzipper 0.4.0 that changes the default behaviour of pyzipper to always use the AE-2 format and exclude the CRC32 values, unless instructed to do otherwise.
If rewriting the zip archive to remove the CRC values for small files, the entire zip archive should be recreated to avoid the original local file header with the CRC included remaining in the zip file in a detached state.
Credit
Thanks to Lucas Lavarello from Kulkan Security for identifying this issue.
References
https://www.winzip.com/en/support/aes-encryption/#CRC https://www.winzip.com/en/support/aes-encryption/#crc-faq
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | pyzipper | all versions | 0.4.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for pyzipper. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update pyzipper to 0.4.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-crqm-m339-7m2p is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-crqm-m339-7m2p is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-crqm-m339-7m2p. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-crqm-m339-7m2p in your dependencies?
O3 detects GHSA-crqm-m339-7m2p across PyPI dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.