Repository navigation
fix: raise the pypdf and urllib3 security floors - #191
Merged
Merged
Conversation
pypdf 6.16.2 through 6.18.1 carry some or all of PYSEC-2026-4153 to 4160, all memory or runtime exhaustion on crafted PDFs; 6.19.0 is the first release clear of all eight. The requirements.txt floor moves from 6.16.2 to 6.19.0, and so does the Flatpak pin (requirements-pinned.txt plus the wheel URL and sha256 in python-modules.yml). The scheduled security-deps.yml run on main (run 37313643981, 2026-10-05) failed its strict gate on the Flatpak pin pypdf==6.16.2, with eight findings; this commit fixes it. The requirements.txt half of that gate passed on the same run although its floor admitted every affected release: "pip-audit -r" audits the newest release that satisfies ">=", not the floor. The floor still matters because builds resolve at build time: build.yml installed pypdf 6.18.1 for every v1.15.0 binary (run 34720950897). PYSEC-2026-4157 is reachable from the app: the editor's form tab sends every field back through PdfWriter.update_page_form_field_values (app/editor/tab.py:1399) with auto_regenerate=True and flatten=False, which still regenerates the appearance stream of /Tx and /Ch fields, although the advisory says it "requires updating form field values with flattening enabled". A 1.4 MB PDF whose multiline /Tx value has 100,000 lines held the GUI thread for 51 s on 6.18.1 against 1.5 s on 6.19.0; the cost grows quadratically with the line count. 4159 and 4160 are not reachable: app/ never calls PdfReader.page_labels or .attachments, the only entry points to the fixed code. The urllib3 floor moves from 2.7.0 to 2.8.0 for PYSEC-2026-4175 / 4176 / 4177 (published 2026-10-01, all affecting 2.7.0). The Flatpak build does not install urllib3. The requirements.txt comments called urllib3 a transitive dependency of cryptography and requests, and idna one of urllib3 and requests. In a venv installed from requirements.txt alone, pip show reports an empty Required-by for both, urllib3 does not depend on idna, and app/ imports neither; only requests, pulled in by pip-audit from requirements-dev.txt, depends on them. The comments now say so. Whether the two entries belong in requirements-dev.txt is left open. tests/test_dependency_security_floors.py fails when a requirements.txt floor for pypdf, cryptography, urllib3, lxml or idna admits a release below the first one clear of every advisory OSV listed on 2026-10-05, or admits a release listed as affected. It also rejects a floor conditioned by an environment marker, since pip skips that line wherever the marker is false. It only knows the advisories it lists, and as of 2026-10-05 no workflow on main runs pytest. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Python dependencies security checkpip-audit:
|
| Package | Pin | Latest on PyPI | Status |
|---|---|---|---|
| PySide6 | PySide6>=6.11.1 |
6.11.2 |
outdated |
| pypdf | pypdf>=6.19.0 |
6.19.0 |
up-to-date |
| cryptography | cryptography>=50.0.1 |
50.0.2 |
outdated |
| qtawesome | qtawesome>=1.4.2 |
1.4.2 |
up-to-date |
| pillow | pillow>=12.3.0 |
12.3.0 |
up-to-date |
| pymupdf | pymupdf>=1.28.0 |
1.28.2 |
outdated |
| pytesseract | pytesseract>=0.3.13 |
0.3.13 |
up-to-date |
| python-docx | python-docx>=1.2.0 |
1.2.0 |
up-to-date |
| python-pptx | python-pptx>=1.0.2 |
1.0.2 |
up-to-date |
| openpyxl | openpyxl>=3.1.5 |
3.1.5 |
up-to-date |
| beautifulsoup4 | beautifulsoup4>=4.15.0 |
4.15.0 |
up-to-date |
| ebooklib | ebooklib>=0.20 |
0.20 |
up-to-date |
| lxml | lxml>=6.1.1 |
6.1.3 |
outdated |
| urllib3 | urllib3>=2.8.0 |
2.8.0 |
up-to-date |
| idna | idna>=3.18 |
3.20 |
outdated |
| pyinstaller | pyinstaller>=6.21.0 |
6.22.3 |
outdated |
Auto-generated by security-deps workflow. Merge is blocked only when pip-audit --strict reports vulnerabilities.
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.
What changes
requirements.txt: the pypdf floor moves from>=6.16.2to>=6.19.0, and the urllib3 floor from>=2.7.0to>=2.8.0. The comments above both entries are rewritten (see below).flatpak/requirements-pinned.txt: the Flatpak pin moves frompypdf==6.16.2topypdf==6.19.0.flatpak/python-modules.yml: the pypdf wheel URL and sha256 are updated to match the 6.19.0 pin.tests/test_dependency_security_floors.py(new): fails when arequirements.txtfloor for pypdf, cryptography, urllib3, lxml or idna admits a release below the first one clear of every advisory OSV listed on 2026-10-05, or admits a release listed as affected. It also rejects a floor conditioned by an environment marker, since pip skips that line wherever the marker is false.Why
pypdf. Releases 6.16.2 through 6.18.1 carry some or all of PYSEC-2026-4153 to PYSEC-2026-4160, all memory or runtime exhaustion on crafted PDFs. 6.19.0 is the first release clear of all eight (and of the six earlier advisories the old floor already covered).
This is not theoretical for shipped builds. Builds resolve dependencies at build time, and
build.ymlinstalled pypdf 6.18.1 for every v1.15.0 binary (run 34720950897), which still carries three of these advisories.PYSEC-2026-4157 is reachable from the app. The editor's form tab sends every field back through
PdfWriter.update_page_form_field_values(app/editor/tab.py:1399) withauto_regenerate=Trueandflatten=False. That path still regenerates the appearance stream of/Txand/Chfields, although the advisory says it "requires updating form field values with flattening enabled". Measured: a 1.4 MB PDF whose multiline/Txvalue has 100,000 lines held the GUI thread for 51 s on 6.18.1 against 1.5 s on 6.19.0, and the cost grows quadratically with the line count. PYSEC-2026-4159 and PYSEC-2026-4160 are not reachable:app/never callsPdfReader.page_labelsor.attachments, the only entry points to the fixed code.Why the audit did not catch the floor.
pip-audit -r requirements.txtaudits the newest release that satisfies>=, not the floor itself. A floor that admits vulnerable releases therefore audits clean for as long as a fixed release exists. The new test closes that blind spot for the five packages it covers.urllib3. PYSEC-2026-4175, PYSEC-2026-4176 and PYSEC-2026-4177 (published 2026-10-01) all affect 2.7.0 and are fixed in 2.8.0. The Flatpak build does not install urllib3.
The old comments called urllib3 a transitive dependency of cryptography and requests, and idna one of urllib3 and requests. In a venv installed from
requirements.txtalone,pip showreports an emptyRequired-byfor both, urllib3 does not depend on idna, andapp/imports neither. Onlyrequests, pulled in by pip-audit fromrequirements-dev.txt, depends on them. The comments now say so.Fixes the red scheduled security-deps run on main
The scheduled
security-deps.ymlrun onmain(run 37313643981, 2026-10-05) failed its strict gate on the Flatpak pinpypdf==6.16.2, with eight findings. This PR moves that pin to 6.19.0 and should turn the gate green. Therequirements.txthalf of the same gate passed on that run, for the reason described above.Limits of the new test
mainruns pytest. That changes once ci: run the test suite on pull requests and pushes to main #190 is merged.Left open (not in this PR)
urllib3andidnashould move fromrequirements.txttorequirements-dev.txt, given that only a dev dependency needs them.🤖 Generated with Claude Code