Repository navigation
fix(deps): bump pypdf to 6.21.4 for factory-local pip-audit - #3773
Conversation
pip-audit flags seven CVEs against pypdf 6.21.2 in packages/factory-local/requirements.lock. Raise the pin to >=6.21.4,<7 (smallest fix for CVE-2026-119203/119204/119205; also covers CVE-2026-119206/119207/119208/119209 fixed in 6.21.3) and regenerate the factory-local and root hashed locks. Root lock also picks up pyasn1 0.6.5 (CVE-2026-119194/119195/119196/119197) so pip-audit stays clean once the check runs. Frontend overrides match #3770 so npm audit --audit-level=high does not fail the same Dependency Audit job. Signed-off-by: Christopher Sellers <1@christophersellers.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes.
|
PR Blocker ChecklistHead SHA: Status: Ready
|
✅ Bundle Size Report
Bundle is within the 10.0MB limit. |
|
Vercel preview: https://regengine-amk6xn891-petrefiedthunders-projects.vercel.app Access is via Vercel login (Deployment Protection). |
Dependency Lock Freshness runs pip-compile on 3.11; the prior lock header and typing-extensions via annotations were from 3.13. Signed-off-by: Christopher Sellers <1@christophersellers.com>
|
Merged main into this branch. There were no conflicts. Local checks: This PR's pypdf 6.21.4 and pyasn1 0.6.5 bump is what clears the Security Audit failures now showing on other open PRs (for example #3761). Landing it early would unblock them. The frontend overrides overlap with #3770, so whichever of the two lands second may need a trivial lockfile rebase. New head SHA: |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0b028a5. Configure here.
The Security Audit, Production Readiness Gate and per-service pip-audit jobs went red on this PR after advisories for pypdf 6.21.2, pyasn1 0.6.4 and follow-redirects 1.16.0-1.16.1 were published. Main is red on the same jobs. This ports #3773 byte for byte (pypdf 6.21.4, pyasn1 0.6.5, npm overrides follow-redirects >=1.16.2 and minimatch >=11.0.1). It no-ops once main carries #3773. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj
PetrefiedThunder
left a comment
There was a problem hiding this comment.
REVIEW: PASS deepseek 0b028a5
Critical-path dep bump: clears main-blocking pip-audit reds on pypdf==6.21.2 and pyasn1==0.6.4.
CVE coverage (OSV + local pip-audit with CI ignore set):
- pypdf 6.21.2 → 7 vulns (CVE-2026-119206/07/08/09 fixed in 6.21.3; CVE-2026-119203/04/05 fixed in 6.21.4). 6.21.4 → 0.
- pyasn1 0.6.4 → 4 vulns (CVE-2026-119194/95/96/97) fixed in 0.6.5. 0.6.5 → 0.
- pip-audit -r packages/factory-local/requirements.lock and requirements.lock: No known vulnerabilities found.
Lock/requirements consistency:
- factory-local requirements.txt + lock: pypdf>=6.21.4,<7 / ==6.21.4
- root requirements.in + lock: same pypdf floor; transitive pyasn1 0.6.4→0.6.5 only (not in .in)
- Python lock diffs are only those two package pins (+ hashes). Frontend overrides add follow-redirects ≥1.16.2 and tighten minimatch ≥11.0.1 so npm audit does not block Dependency Audit before pip-audit — same intent as #3770, not an unrelated feature bump.
CI on this head: Dependency Audit pass; Security Audit (+ service audits) pass; Dependency Lock Freshness pass. Remaining reds are Engine Review Pass (this review) and known gate/blocker / stale Head SHA runs (current Head SHA Check Guard / status pass).
Tests: packages/factory-local pytest -m "not integration" → 11 passed on pypdf 6.21.4.
Merging main (6887ca5) brought in pins that the Security Audit, Production Readiness Gate and per-service pip-audit jobs now reject: pypdf 6.21.2, pyasn1 0.6.4 and follow-redirects 1.16.0-1.16.1. Main is red on the same jobs. This ports #3773 byte for byte (pypdf 6.21.4, pyasn1 0.6.5, npm overrides follow-redirects >=1.16.2 and minimatch >=11.0.1), as already done on #3767. It no-ops once main carries #3773. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj
Merge commit only (no rebase). Brings landed pypdf bump and admin RLS test. Signed-off-by: PetrefiedThunder <1@christophersellers.com>
Merge commit only (no rebase) so Security Audit can clear on current main pins. Signed-off-by: Christopher <131207452+PetrefiedThunder@users.noreply.github.com>
Brings in #3773 (pyasn1 0.6.5, pypdf 6.21.4, follow-redirects 1.16.2, minimatch 11.0.3), which clears the pip-audit and npm audit failures this PR's CI hit on 767d36f from new upstream advisories. No conflicts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYEfpvtBTjWGrzsiaDL
…erive waiver approvers from the principal (#3717) * feat(evidence): enforce the traceability_events mutation policy and derive waiver approvers from the principal S4 (fsma.traceability_events mutation policy). The canonical FSMA 204 evidence table had no database-level guard: any role with UPDATE could rewrite the payload the chain hash covers, while fsma.cte_events has had an append-only trigger since v107. Migration v138 (08c7cf36ddbe) adds a BEFORE UPDATE OR DELETE row trigger and a BEFORE TRUNCATE statement trigger that allow exactly what the production writers do: the amendment path (status active -> superseded, amended_at) and the rules engine markers (evaluation_verdict, no_verdict_reason, evaluation_error, evaluated_at). Every other column change, any other status transition, DELETE and TRUNCATE raise check_violation. The comparison is to_jsonb(NEW) - allowlist = to_jsonb(OLD) - allowlist, so it holds on every catalog variant of the table and keeps covering columns added later. Break-glass is the existing fsma.allow_mutation GUC, transaction-local; no grant changes. Six live tests that legitimately mutate the table (tamper simulations, cleanups, an orphaning helper) now set the GUC inside their transaction. SCHEMA_CHANGE_POLICY.md section 5 gains the sanctioned mutation surface (5.1) and the SEL-589 read freeze on fsma.cte_events and fsma.critical_tracking_events (5.2). S5 (waiver approver from the principal). PATCH /exceptions/{id}/waive took waiver_approved_by from the request body, so a caller could sign a waiver in anyone's name. The approver is now the authenticated principal's key_id (401 when empty), the same rule the FDA export audit identity follows; a body-supplied value is ignored. The frontend still sends the field and is unaffected. Tests: static and behavioural v138 tests against a live PostgreSQL (allowlisted updates, the one status transition, rejected payload updates and transitions, DELETE, TRUNCATE, break-glass, transaction locality, idempotent re-apply, downgrade), chain health, revision checker; exception router tests for the derived approver, ignored body field, missing reason and empty principal. Live suites touched by the GUC change pass against the scratch database at v138. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj * ci(evidence): satisfy the secrets and tenant_id guards on the v138 files Mark the two revision-id asserts in the v138 test as allowlisted secrets (detect-secrets flags any 12-hex literal) and reword the migration docstring so the tenant_id UUID-only guard no longer matches the phrase describing the Supabase twin's column type. No behaviour change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj * fix(scripts): spell the key-dir mode as stat.S_IRWXU for the Semgrep gate Ported from #3736. The Semgrep OWASP hard gate on main has flagged scripts/create_test_api_key.py:140 (insecure-file-permissions) since #3625 and the main merge carried the finding into this branch. The directory mode is unchanged (owner read, write and execute only; the key file itself stays 0600). This no-ops once main carries the fix. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj * fix(evidence): make the v138 status-transition guard null-safe The alembic catalog declares traceability_events.status NOT NULL, but the Supabase twin leaves it nullable. With a NULL on either side, NOT (OLD.status = 'active' AND NEW.status = 'superseded') evaluates to NULL rather than TRUE, so the trigger let active -> NULL and NULL -> active through without break-glass; a NULL status would drop the row from the status = 'active' predicates the recall and FDA exports use. The guard now uses IS NOT TRUE. Behavioural test drops the NOT NULL constraint inside transactions the rejection rolls back, covers both directions, and checks the constraint is intact afterwards. Static test pins the null-safe form. Reproduced (DID NOT RAISE) before the change; 23 v138 tests pass after it against a scratch PostgreSQL 16 re-upgraded to v138. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj * fix(db): rechain #3717 mutation policy as v141 after main's v140 #3729 merged v140 (b8c1e4f2a901) to main; #3717's 08c7cf36ddbe still revised a3f7ce361b0e and left Alembic with two heads. Merge main, set down_revision to b8c1e4f2a901, and renumber the label to v141. Revision ID unchanged. Do not apply to prod without C.Lee yes. Signed-off-by: Christopher Sellers <1@christophersellers.com> * test(evidence): bound v141 trigger DDL lock wait, assert SQLSTATE directly, prove waiver replay is a no-op CodeRabbit review on #3717: - v141 upgrade() and downgrade() now run `SET LOCAL lock_timeout = '10s'` before the trigger DDL (same bound as v134), so a CREATE/DROP TRIGGER queued behind a long ingest or export transaction fails fast and can be retried instead of holding every later writer behind it. - The migration tests assert `exc.value.orig.sqlstate == "23514"` with no fallback; rls_db forces psycopg 3, which always exposes it. - New live test tests/shared/test_exception_waiver_replay_live.py drives the real router and ExceptionQueueService against a schema-at-head PostgreSQL: PATCH /waive twice for one case leaves exactly one signoff (signed by the principal, never the body) and one status-change comment. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj * test(evidence): pin that clearing a protected column to NULL is rejected by v141 Cursor Bugbot on #3717 claimed to_jsonb(NEW) drops SQL NULL fields, so a non-allowlisted column could be cleared past the trigger. Reproduced against a scratch PostgreSQL at v141: to_jsonb keeps a NULL column as a null-valued key, and clearing a populated sha256_hash, chain_hash, product_reference or from_facility_reference raises check_violation, including behind a sanctioned status or verdict update. The only "allowed" case is NULL -> NULL, which changes nothing. This test populates those columns through break-glass and pins the rejection. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj * fix(deps): port #3773 pypdf, pyasn1 and follow-redirects bumps Merging main (6887ca5) brought in pins that the Security Audit, Production Readiness Gate and per-service pip-audit jobs now reject: pypdf 6.21.2, pyasn1 0.6.4 and follow-redirects 1.16.0-1.16.1. Main is red on the same jobs. This ports #3773 byte for byte (pypdf 6.21.4, pyasn1 0.6.5, npm overrides follow-redirects >=1.16.2 and minimatch >=11.0.1), as already done on #3767. It no-ops once main carries #3773. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyhDYG3ddQvVKyu2qtYfCj --------- Signed-off-by: Christopher Sellers <1@christophersellers.com> Signed-off-by: PetrefiedThunder <1@christophersellers.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

Summary
packages/factory-local/requirements.lockpinnedpypdf==6.21.2.pip-auditreports seven CVEs on that version. Smallest fixed release is 6.21.4.Advisories
Fixed in 6.21.3: CVE-2026-119206, CVE-2026-119207, CVE-2026-119208, CVE-2026-119209 (also GHSA-42gh-23hr-vphw, GHSA-4vqv-7265-gm2w, GHSA-62m5-6wh8-28x7, GHSA-x3rh-gjgm-fmqc).
Fixed in 6.21.4: CVE-2026-119203, CVE-2026-119204, CVE-2026-119205 (also GHSA-5849-834g-hvw5, GHSA-cggf-277g-3q54, GHSA-mfr5-77xh-9j7h).
Changes
packages/factory-local/requirements.txtand lock:pypdf>=6.21.4,<7/pypdf==6.21.4.requirements.inand rootrequirements.lock: same pypdf floor; root lock also moves transitivepyasn10.6.4 → 0.6.5 (CVE-2026-119194/119195/119196/119197) so the pip half of Dependency Audit stays clean.follow-redirectsandminimatch(same as fix(frontend): patch follow-redirects and minimatch for npm audit #3770) sonpm audit --omit=dev --audit-level=highdoes not fail the Dependency Audit job before pip-audit runs.Test plan
pip-audit -r packages/factory-local/requirements.lock(with CI ignores) — cleanpip-audit -r requirements.lock(with CI ignores) — cleannpm audit --omit=dev --audit-level=high— exit 0packages/factory-local:pytest -m "not integration"— 11 passedReview requested: DeepSeek
Note
Low Risk
Patch-level dependency and lockfile updates for known CVEs; no application logic changes, though pypdf handles untrusted PDF input in factory-local.
Overview
Raises pypdf from 6.21.2 to 6.21.4 in
packages/factory-local, rootrequirements.in, and both pip lockfiles sopip-auditclears seven advisories on the old pin (factory-local uses pypdf for LegiScan PDF text extraction).Root
requirements.lockalso bumps transitive pyasn1 0.6.4 → 0.6.5 for related CVEs.requirements.inCVE comments are updated for the 6.21.3/6.21.4 fixes.On the frontend, npm overrides add
follow-redirects≥1.16.2 and tighten minimatch to ≥11.0.1 (with lockfile updates for those transitive versions) so Dependency Audit’snpm auditstep passes before pip-audit runs.Reviewed by Cursor Bugbot for commit 0b028a5. Bugbot is set up for automated code reviews on this repo. Configure here.