Files
jobtrackingapp/docs/redesign/phase-9/p9-remed-02/security/REMEDIATION.md
T

51 lines
7.6 KiB
Markdown

# Python security remediation — 24 October 2026
**Verdict: BLOCKED for remaining model-runtime qualification; no owner risk acceptance.** Five bounded dependency upgrades remove65 of109 baseline advisory alias groups from the locked graph. Remaining44 groups are recorded individually, not suppressed. This is local development evidence, not a deployed fix.
## Exact changes and reproducibility
| Package | Before | After | Selection and compatibility |
| --- | --- | --- | --- |
| Pillow |12.3.0 |13.0.0 |Published parser fixes include JPEG/APNG/EXIF paths. Python3.12 is supported; removed APIs were checked against the actual Image.open/convert/OCR call sites. No removed API is called by the sidecar. |
| pypdf |6.16.2 |6.21.2 |Latest reviewed6.x security patch; PdfReader/pages/extract_text contract retained and benign PDF content checked. |
| certifi |2026.7.22 |2026.10.19 |Removes affected compromised CA trust; transitive Requests/Hugging Face use. |
| urllib3 |2.7.0 |2.8.0 |Patched proxy/chunk/deflate handling; no service routing/API changes. |
| setuptools |84.0.0 |84.1.0 |Patched legacy wheel/namespace installation path. Runtime performs no package installation. |
Primary upstream evidence: [Pillow13 security and compatibility notes](https://pillow.readthedocs.io/en/stable/releasenotes/13.0.0.html), [pypdf6.21.2 changelog](https://pypdf.readthedocs.io/en/stable/meta/CHANGELOG.html), [certifi advisory](https://github.com/advisories/GHSA-6q48-6c7w-9gw2). All per-advisory primary links, exact affected ranges, published fix events and severity labels are retained in [the inventory](advisory-inventory.json).
The existing UV0.12.7 Linux hash-lock command was reused with Python3.12/x86_64 Linux and the CPU Torch index. Exactly five versions changed among49 pins; no other package/version was added, removed or upgraded. `requirements.txt` declares the three previously transitive TLS/build pins explicitly as reviewed security constraints. The hash lock contains actual distribution hashes; five downloaded Linuxcp312 wheels were independently hashed and matched against it. No Torch or model artifact was downloaded. Existing application source, models, parser limits, API, withholding policy and production Dockerfile are unchanged.
Reproduce from `tools/summarizer` using the installed UV runtime:
```powershell
rtk proxy .venv/Scripts/python.exe -m uv pip compile requirements.txt --generate-hashes --python-version 3.12 --python-platform x86_64-unknown-linux-gnu --torch-backend cpu --output-file requirements-linux.lock
rtk proxy .venv/Scripts/python.exe -m pytest -q tests
rtk proxy .venv/Scripts/python.exe -m pip check
```
Keep an original lock copy and compare exact membership before replacing it. Regeneration reuses current lock pins; a clean resolution without that output may choose different transitive versions. Production installs continue to require hashes from the committed lock. Local Windows validation installed only the five exact changes without resolving unrelated dependencies and `pip check` passes.
## Regression evidence
- Baseline bounded APNG regression:1 failed/1 passed. A64-pixel synthetic APNG demonstrably allocated the full rejected canvas before the decompression-bomb check on Pillow12.3.0; no large/malicious allocation was attempted. This directly covers GHSA-5xm2-6676-qcp9's operation ordering.
- Patched complete sidecar suite: **58/58 passed**, zero skipped, comprising56 existing cases plus2 added parser-security cases. The second truncated-xref case already passed on the old pypdf pin; it is not claimed as a RED reproduction of that pin. A five-second child deadline prevents an unbounded regression hang.
- Real local uvicorn startup: health reports model disabled/unloaded and unavailable local summarization. Actual token-protected uploads of synthetic TXT/DOCX/PDF preserve content including `Åse Østby ærlig` and `Python and C#`; missing-token upload returns401. The owned process is stopped afterward. This uses actual HTTP and parser children, not an AI model.
- Supplemental **Linux Python3.12.10 parser** check:2/2 added regressions pass plus3/3 actual resource-bounded child TXT/DOCX/PDF decodes preserving the same content. It runs nonroot in a read-only, network-none, capability-dropped container with512MiB/oneCPU limits; no daemon socket, host port or persistent data. The container is removed. Pytest emits one `cache_dir` warning because its cache plugin is disabled; no case is skipped or retried.
The supplemental Linux image contains the exact reviewed parser/TLS changes and small test dependencies; it is **not** the complete49-package sidecar graph and runs no OCR/model inference. Its image/source/process identities are in validation.json. An existing cached sidecar image was inspected and found to use Python3.11.16/FastAPI0.115.12/Pillow11.1/pypdf5.4; it was not relabelled as the current3.12 hash-lock runtime.
Raw logs, TRX-equivalent JUnit, before/after queries, source identities and synthetic originals remain under `.artifacts/p9-remed-02/security/`. Focused/supplemental checks are not added to the complete58 total.
## Fresh advisory accounting and remaining actions
Fresh exact OSV/PyPI queries:49 pins,98 requests before and98 after; each has97 successes and one retained PyPI404 for vendor version `torch==2.6.0+cpu`. Exact OSV CPU-version lookup succeeds. The missing PyPI vendor release is explained but remains an incomplete second-provider result; no upstream-version substitution is represented as exact vendor coverage.
Before:249 provider records,109 published alias groups across8 packages. After:99 records,44 groups across3 packages — filelock3, Torch19, Transformers22.65 groups no longer match the updated exact lock. Alias groups are not independent CVE or exploit counts. [ADVISORIES.md](ADVISORIES.md) indexes every baseline group and its current disposition; [JSON](advisory-inventory.json) retains all mandatory per-row fields.
Filelock4 changes some shared-cache/on-disk lock protocols; the inspected Hugging Face helper uses FileLock with a SoftFileLock fallback, not ReadWriteLock. No runtime/cache migration was attempted. The Windows fallback/local-marker condition still needs a narrow compatibility/ownership assessment. Read the [upstream protocol warning](https://py-filelock.readthedocs.io/en/latest/changelog.html#id162) before a shared-cache transition; no live cache participant may be silently mixed.
Torch/Transformers records include many alternative model, conversion, Trainer, optimizer and compiler operations with no matching application call found. Those absences are explicitly source-limited. Fixed-repository `from_pretrained` loading still exists without an immutable revision/artifact integrity record; actual checkpoint format and model dependency internals remain unqualified. The standard user cache contained no DistilBART snapshot, and no model download/inference was attempted. Some provider records describe other library versions/model families; the inventory retains those ranges and does not assert a reproduced exploit in this application.
Next security action: select and validate a compatible patched Torch/Transformers CPU graph for the existing model, verify immutable model/tokenizer/checkpoint identities, startup and representative inference/extraction contracts in an approved local environment. Alternatively, the product/security owner must explicitly decide any serious residual risk after applicability evidence. This task does not accept it for them. Container isolation, resource limits and mocked inference tests do not close that gate. Bootstrap pip/wheel, base OS/OCR libraries and actual production identities remain separate release audit obligations.