7.4 KiB
Python locked advisory gate: OPEN
The Python sidecar dependency gate remains OPEN, with INCOMPLETE advisory coverage. NuGet/npm remediation is a separate result and cannot close this gate. No Python dependency, lockfile, model, parser or runtime was changed during this review.
The 2026-10-24 07:27:05-07:27:13 UTC review queried all 49 exact pins in tools/summarizer/requirements-linux.lock through the public OSV version query and PyPI release-specific JSON APIs: 98 queries, 97 successes, one error. PyPI returns 404 for the vendor CPU version torch==2.6.0+cpu; its exact OSV query succeeds. No substitute torch==2.6.0 query or dependency resolution was used.
The responses contain 249 provider records (137 OSV, 112 PyPI), combined by published alias equivalence into 109 advisory groups across eight packages. These are separate counts; the groups are not a claim of 109 independent CVEs. No returned group has withdrawn metadata in this snapshot.
| Exact affected query pin | Published alias groups |
|---|---|
| certifi 2026.7.22 | 1 |
| filelock 3.32.4 | 3 |
| pillow 12.3.0 | 41 |
| pypdf 6.16.2 | 19 |
| setuptools 84.0.0 | 1 |
| torch 2.6.0+cpu | 19 |
| transformers 4.48.3 | 22 |
| urllib3 2.7.0 | 3 |
python-advisories.json retains exact membership, every group ID/alias, package/version, published primary record links, fixed-version events and provider database_specific.severity labels. No severity score was invented. Fixed events can differ by branch and are not a compatible upgrade selection. Raw byte responses, query scopes, timestamps, response hashes, parser self-check and membership/accounting checks remain in .artifacts/p9-requal-01/security/python-locked/.
- Lock SHA-256:
36f2912965d183e59f2d8320f3817ca8dd0fee6d76e05cfd63ac92defe6c6031. - Raw 202-file evidence manifest SHA-256:
3dac31a50d803e4c4a27c43e683dcf7ee7f2587a122cfb8c38fc5276fb7233ec. - Raw aggregate response summary SHA-256:
31fe495d72a9b11564c8e78943be7901610e023a8606b5aeb53710871092ca20.
API semantics: OSV version query/pagination and PyPI release-specific vulnerabilities. This is public advisory metadata, not exploit testing or a deployed package inventory.
Observed sidecar call sites
Static source inspection was made at checkout HEAD 780b9bc64f0923237c5a03f89d240bbe331f058e; the hashes below identify the actual files read. It establishes application call sites and existing bounds only. It does not determine whether each advisory is reachable, reproduce an exploit or establish production exposure.
| Surface | Verified source evidence | Qualification |
|---|---|---|
| Uploaded document entry | tools/summarizer/app.py:1317-1336: /extract-text accepts uploaded bytes, checks empty/5 MiB input, extension allowlist and signature, then calls _run_parser_child. File/pixel defaults are at app.py:99-110. |
PDF and image parsers have a route from uploaded documents. No malicious upload or live request was made. |
| PyPDF | tools/summarizer/parser_child.py:158-178: constructs PdfReader(io.BytesIO(data)), obtains pages, enforces 40-page default and calls page.extract_text(extraction_mode="layout") with compatibility fallback. |
Reader construction/page enumeration occurs before the explicit page-count check. This call site does not map or dismiss individual advisory conditions. |
| Pillow image path | tools/summarizer/parser_child.py:150-155: Image.open on uploaded image bytes, image-size check, then OCR; _ocr_image can call image.convert("RGB") at lines 142-147. Allowed image extensions are PNG/JPEG/WebP at line 26. |
Opening occurs before application size validation. An allowlist/size check is not evidence that Pillow advisories are eliminated. |
| PDF OCR fallback | tools/summarizer/parser_child.py:178-202: short extracted text falls back to fitz.open, rasterizes pages, checks per-page/total pixel budgets, then opens PNG bytes through Pillow for OCR. |
Pillow is also used on renderer-produced PNGs. Rasterization occurs before the explicit pixel-budget check. No claim is made about a specific advisory's applicability. |
| Child execution bounds | tools/summarizer/app.py:1196-1208,1260-1314: allowlisted child environment, one parser capacity slot, separate temporary directory/process group, default 25-second timeout and result-size checks; timeout termination is at lines 1232-1251 and 1292-1299. parser_child.py:35-44,237-239 applies POSIX CPU/address-space/file/descriptor/core limits before extraction. |
These are existing application controls. POSIX limits return without application on non-POSIX systems. A child process/resource bound is not proof of a security sandbox or closure of parser advisories. |
| Transformers/model loading | tools/summarizer/app.py:4,19,96,161-169: imports Transformers and torch; fixed repository name sshleifer/distilbart-cnn-12-6; AutoTokenizer.from_pretrained(MODEL_NAME) and AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME). |
Calls have no explicit revision, trust_remote_code, weights_only or use_safetensors argument in this source. No runtime serialization format, downloaded revision, dependency default or model safety property was verified. |
| Local inference | tools/summarizer/app.py:172-195,512-518: lazy/eager runtime loading, tokenizer invocation and model.generate; disabled-load path is explicit at lines 174-176. |
No model was loaded or executed for this review. Test-time load disabling does not adjudicate the deployed inference path. |
| Direct deserialization search | A search of sidecar Python sources for torch.load, weights_only, trust_remote_code, use_safetensors and revision= found no explicit call/argument. |
Absence in application source does not establish absence in Transformers/torch internals. Those third-party runtime paths were not traced. |
| Service access | tools/summarizer/app.py:38-42,59-68: optional service token middleware rejects mismatched/missing headers when the token is configured; health is exempt. |
Runtime token/network configuration was not inspected. Conditional authentication is not an advisory mitigation verdict. |
| Installation boundary | tools/summarizer/Dockerfile:14-16: copies the Linux lock, upgrades bootstrap pip setuptools wheel, then installs with --require-hashes and the PyTorch CPU extra index. Runtime switches to user app at lines 18-22. |
Explains the +cpu pin's external index. This lock-only advisory audit excludes bootstrap version drift, base image, native OS/OCR libraries and actual built/deployed identities. |
Inspected source SHA-256 values:
| File | SHA-256 |
|---|---|
tools/summarizer/app.py |
a721a7633f7ed93b7353f2135536a168e096494629506634c96b456b7ae713c2 |
tools/summarizer/parser_child.py |
0074a05e9a0d511e26a329a057f98568cdc1723b2cc37168e0b59975b5424451 |
tools/summarizer/Dockerfile |
d0b8777e81a74ed7099fe1d93f608b6601da39efc43b50ec0b3b058613207443 |
Required next decision
The owner must decide a separately scoped Python/ML/parser dependency remediation with compatible lock generation, model-loading/inference validation and representative benign document parsing/regression checks, or explicitly retain the open gate. A major ML/parser upgrade is not safe to perform automatically inside this requalification checkpoint. Existing controls and passing mocked/unit tests do not clear these advisory records; there is no current Python security PASS.