Security review Oct 2026: completed fixes (Next/Node upgrade, staff tokens, upload/submit hardening) #3

Open
opened 2026-10-30 11:50:12 -07:00 by joelbrock · 0 comments
Owner

Record of the security fixes from the Oct 29–30, 2026 review. They were prompted by PHP2Shell (CVE-2026-109618/-109619), Node2Shell (CVE-2026-111497) and the eMudhra CA compromise, followed by a full review of the app and the CiviCRM extension.

PR #1: merged and deployed to Amplify ✅

  • Next.js 16.2.6 → 16.4.3 (Critical). It fixes ~20 advisories, including unauthenticated RCE in the Image Optimization API (GHSA-2xp9-vwfh-vxw4, GHSA-2464-fhr4-w9xw) and SSG/ISR cache poisoning (GHSA-mcj8-r9mp-w47p). npm audit: 6 → 0 vulnerabilities.
  • Node 20 → 24 LTS (High). Node 20 is end-of-life and gets no Node2Shell fix. Amplify picked up Node 24 from .nvmrc without any console changes.

PR #2: open, pending merge + extension rollout

Finding Fix Commit
#3 High: the raw STAFF_REPORT_KEY was in the iframe URL for every Civi user, with no contact ACL check, so any org's report and files were reachable Signed, org-bound, 8h HMAC tokens minted by Tab.php after Contact_Permission::allow(VIEW); extension 0.4.0 818c979
#6 Medium: the verifyChecksum fallback could accept any checksum Fails closed on any API error c9b6105
#5 Medium: the extension upload endpoint had no CSRF protection, no record ACL check and no mime check Requires X-Requested-With, EDIT permission on the target record and a mime allowlist 0a19b57
#4 Medium: /api/submit trusted client-supplied file ids File id must be uploaded by this contact or match the org's current value df471e0
#8 Low–Med: preview-link was gated by HEALTH_TOKEN in the query string PREVIEW_ADMIN_TOKEN Bearer header (falls back to HEALTH_TOKEN until set); constant-time compares 526422a

Rollout checklist

  • Merge PR #1 → Amplify deploy
  • Merge PR #2 → Amplify deploy (the legacy ?key= still works, so the tab keeps working)
  • Package with git archive --format=zip --prefix=webform-mw/ -o webform-mw-0.4.0.zip HEAD:civi-extension/webform-mw
  • Install extension 0.4.0 on client.crm.fci.coop, cv flush, verify
  • Install extension 0.4.0 on crm.fci.coop, cv flush, verify
  • Verify the iframe src has exp=&sig= and no key=; the attachment lightbox works; a form upload + submit works end to end
  • Remove legacy ?key= support (tracked in the follow-up issue)
  • Optional: add PREVIEW_ADMIN_TOKEN to Amplify Secrets

Remaining items are tracked in the follow-up issue.

Record of the security fixes from the Oct 29–30, 2026 review. They were prompted by PHP2Shell (CVE-2026-109618/-109619), Node2Shell (CVE-2026-111497) and the eMudhra CA compromise, followed by a full review of the app and the CiviCRM extension. ## PR #1: merged and deployed to Amplify ✅ - **Next.js 16.2.6 → 16.4.3** (Critical). It fixes ~20 advisories, including unauthenticated RCE in the Image Optimization API (GHSA-2xp9-vwfh-vxw4, GHSA-2464-fhr4-w9xw) and SSG/ISR cache poisoning (GHSA-mcj8-r9mp-w47p). `npm audit`: 6 → 0 vulnerabilities. - **Node 20 → 24 LTS** (High). Node 20 is end-of-life and gets no Node2Shell fix. Amplify picked up Node 24 from `.nvmrc` without any console changes. ## PR #2: open, pending merge + extension rollout | Finding | Fix | Commit | |---|---|---| | #3 High: the raw `STAFF_REPORT_KEY` was in the iframe URL for every Civi user, with no contact ACL check, so any org's report and files were reachable | Signed, org-bound, 8h HMAC tokens minted by `Tab.php` after `Contact_Permission::allow(VIEW)`; extension **0.4.0** | 818c979 | | #6 Medium: the `verifyChecksum` fallback could accept any checksum | Fails closed on any API error | c9b6105 | | #5 Medium: the extension upload endpoint had no CSRF protection, no record ACL check and no mime check | Requires `X-Requested-With`, EDIT permission on the target record and a mime allowlist | 0a19b57 | | #4 Medium: `/api/submit` trusted client-supplied file ids | File id must be uploaded by this contact or match the org's current value | df471e0 | | #8 Low–Med: preview-link was gated by `HEALTH_TOKEN` in the query string | `PREVIEW_ADMIN_TOKEN` Bearer header (falls back to `HEALTH_TOKEN` until set); constant-time compares | 526422a | ## Rollout checklist - [x] Merge PR #1 → Amplify deploy - [ ] Merge PR #2 → Amplify deploy (the legacy `?key=` still works, so the tab keeps working) - [ ] Package with `git archive --format=zip --prefix=webform-mw/ -o webform-mw-0.4.0.zip HEAD:civi-extension/webform-mw` - [ ] Install extension 0.4.0 on **client.crm.fci.coop**, `cv flush`, verify - [ ] Install extension 0.4.0 on **crm.fci.coop**, `cv flush`, verify - [ ] Verify the iframe `src` has `exp=&sig=` and no `key=`; the attachment lightbox works; a form upload + submit works end to end - [ ] Remove legacy `?key=` support (tracked in the follow-up issue) - [ ] Optional: add `PREVIEW_ADMIN_TOKEN` to Amplify Secrets Remaining items are tracked in the follow-up issue.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: designslife/WebForm-mw#3