Moderate severityNVD Advisory· Published Feb 26, 2026· Updated Feb 26, 2026
pypdf: Manipulated FlateDecode XFA streams can exhaust RAM
CVE-2026-27888
Description
pypdf is a free and open-source pure-python PDF library. Prior to 6.7.3, an attacker who uses this vulnerability can craft a PDF which leads to the RAM being exhausted. This requires accessing the xfa property of a reader or writer and the corresponding stream being compressed using /FlateDecode. This has been fixed in pypdf 6.7.3. As a workaround, apply the patch manually.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
pypdfPyPI | < 6.7.3 | 6.7.3 |
Affected products
1Patches
17a4c8246ed48SEC: Use zlib decompression limit when retrieving XFA data (#3658)
2 files changed · +32 −4
pypdf/_doc_common.py+2 −3 modified@@ -29,7 +29,6 @@ # POSSIBILITY OF SUCH DAMAGE. import struct -import zlib from abc import abstractmethod from collections.abc import Generator, Iterable, Iterator, Mapping from datetime import datetime @@ -61,6 +60,7 @@ from .constants import FieldDictionaryAttributes as FA from .constants import PageAttributes as PG from .errors import PdfReadError, PyPdfError +from .filters import _decompress_with_limit from .generic import ( ArrayObject, BooleanObject, @@ -1324,7 +1324,6 @@ def is_encrypted(self) -> bool: @property def xfa(self) -> Optional[dict[str, Any]]: - tree: Optional[TreeObject] = None retval: dict[str, Any] = {} catalog = self.root_object @@ -1342,7 +1341,7 @@ def xfa(self) -> Optional[dict[str, Any]]: if isinstance(f, IndirectObject): field = cast(Optional[EncodedStreamObject], f.get_object()) if field: - es = zlib.decompress(field._data) + es = _decompress_with_limit(field._data) retval[tag] = es return retval
tests/test_doc_common.py+30 −1 modified@@ -11,11 +11,13 @@ import pytest from pypdf import PdfReader, PdfWriter -from pypdf.errors import PdfReadError +from pypdf.errors import LimitReachedError, PdfReadError +from pypdf.filters import FlateDecode from pypdf.generic import ( ArrayObject, DictionaryObject, EmbeddedFile, + EncodedStreamObject, NameObject, NullObject, TextStringObject, @@ -552,3 +554,30 @@ def test_get_outline__cyclic_references__nested_handling(caplog): ] ] assert caplog.messages[0].startswith("Detected cycle in outline structure for {") + + +def test_xfa__decompression_limit(): + payload = b"A" * 100_0000 + compressed = FlateDecode.encode(payload, 9) + + writer = PdfWriter() + writer.add_blank_page(width=72, height=72) + + stream = EncodedStreamObject() + stream._data = compressed + stream[NameObject("/Filter")] = NameObject("/FlateDecode") + stream_reference = writer._add_object(stream) + + acro = DictionaryObject() + acro[NameObject("/XFA")] = ArrayObject([TextStringObject("datasets"), stream_reference]) + writer.root_object[NameObject("/AcroForm")] = writer._add_object(acro) + + data = BytesIO() + writer.write(data) + data.flush() + + reader = PdfReader(data) + with mock.patch("pypdf.filters.ZLIB_MAX_OUTPUT_LENGTH", 75_000), pytest.raises( + expected_exception=LimitReachedError, match=r"^Limit reached while decompressing. 902 bytes remaining.$" + ): + _ = reader.xfa
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-x7hp-r3qg-r3cjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-27888ghsaADVISORY
- github.com/py-pdf/pypdf/commit/7a4c8246ed48d9d328fb596942271da47b6d109cghsax_refsource_MISCWEB
- github.com/py-pdf/pypdf/pull/3658ghsax_refsource_MISCWEB
- github.com/py-pdf/pypdf/releases/tag/6.7.3ghsax_refsource_MISCWEB
- github.com/py-pdf/pypdf/security/advisories/GHSA-x7hp-r3qg-r3cjghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.