Security (1/5): FlateDecode/zlib limits — CVE-2025-55197, CVE-2026-27026, CVE-2026-41312#1
Merged
Merged
Conversation
A crafted FlateDecode stream could exhaust memory (a small "zip bomb" inflating to gigabytes — CVE-2025-55197) or, when malformed, pin the CPU in the byte-by-byte zlib recovery fallback (CVE-2026-27026). Rewrite `decompress()` to: - cap decompressed output at ZLIB_MAX_OUTPUT_LENGTH (75 MB) using zlib.decompressobj().decompress(data, max_length) and checking unconsumed_tail (Py2.7-compatible), raising PdfReadError when exceeded; - cap the malformed-stream recovery scan at ZLIB_MAX_RECOVERY_INPUT_LENGTH (5 MB) and also enforce the output cap there. Mirrors upstream pypdf 6.0.0 (PR py-pdf#3430) and 6.7.1 (PR py-pdf#3644). Upstream raises LimitReachedError; this backport reuses the existing PdfReadError to avoid changing the public exception surface (for a memory/CPU bomb, raising any exception defuses it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A crafted FlateDecode stream with a PNG /Predictor and an enormous /Columns value made the per-row prediction buffer (rowlength = columns + 1) allocate unbounded memory. Reject /Columns greater than FLATE_MAX_COLUMNS (250000) with PdfReadError before any per-row allocation. Mirrors upstream pypdf 6.10.2 (PR py-pdf#3734); the upstream /Colors and /BitsPerComponent guards are N/A here because 1.28.x FlateDecode only uses /Columns for the row length. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Backports upstream pypdf security hardening to the PyPDF2 1.28.6 (Py2.7) line by adding explicit limits around FlateDecode/zlib decompression to mitigate DoS vectors (zip-bomb output growth, unbounded recovery scanning, and excessive PNG predictor /Columns).
Changes:
- Add module-level caps for FlateDecode output size, recovery-scan input size, and PNG predictor
/Columnsmaximum. - Update
decompress()to enforce output and recovery-scan limits and raisePdfReadErrorwhen exceeded. - Add regression tests covering the new limits and a basic roundtrip decode.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
PyPDF2/filters.py |
Implements Flate/zlib decompression and predictor parameter caps, raising PdfReadError on limit violations. |
Tests/test_security_flate.py |
Adds regression tests for the decompression output cap, recovery input cap, and /Columns cap. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 1 of 5 of the PyPDF2 1.28.6 security backport (last Py2.7-compatible line), targeting
1.28.6.x. Scoped toPyPDF2/filters.pyFlate/zlib paths./Columns(250000)Backported from upstream pypdf 6.0.0 / 6.7.1 / 6.10.2; adapted Py2.7-safe. Limits raise
PdfReadError(upstream'sLimitReachedErroris avoided to keep these 5 PRs independent). New tests:Tests/test_security_flate.py(5). Validated under Python 2.7.18 — no new failures vs the pristine 1.28.6 baseline.🤖 Generated with Claude Code