6.3 KiB
Security Remediation Plan — DoD Failures (CodeQL + Trivy)
Created: 2026-01-09
This plan addresses the HIGH/CRITICAL security findings reported in docs/reports/qa_report.md.
The prior Codecov patch-coverage plan was moved to docs/plans/patch_coverage_spec.md.
Goal
Restore DoD to ✅ PASS by eliminating all HIGH/CRITICAL findings from:
- CodeQL (Go + JS) results produced by Security: CodeQL All (CI-Aligned)
- Trivy results produced by Security: Trivy Scan
Hard constraints:
- Do not weaken gates (no suppressing findings unless a false-positive is proven and documented).
- Prefer minimal, targeted changes.
- Avoid adding new runtime dependencies.
Scope
From the QA report:
CodeQL Go
- Rule:
go/email-injection(CRITICAL) - Location:
backend/internal/services/mail_service.go(reported around lines ~222, ~340, ~393)
CodeQL JS
- Rule:
js/incomplete-hostname-regexp(HIGH) - Location:
frontend/src/pages/__tests__/ProxyHosts-extra.test.tsx(reported around line ~252)
Trivy
QA report note: Trivy filesystem scan may be picking up workspace caches/artifacts (e.g., .cache/go/pkg/mod/... and other generated directories) in addition to repo-tracked files, while the image scan may already be clean.
Step 0 — Trivy triage (required first)
Objective: Re-run the current Trivy task and determine whether HIGH/CRITICAL findings are attributable to:
- Repo-tracked paths (e.g.,
backend/go.mod,backend/go.sum,Dockerfile,frontend/, etc.), or - Generated/cache paths under the workspace (e.g.,
.cache/,**/*.cover,codeql-db-*, temporary build outputs).
Steps:
- Run Security: Trivy Scan.
- For each HIGH/CRITICAL item, record the affected file path(s) reported by Trivy.
- Classify each finding:
- Repo-tracked: path is under version control (or clearly part of the shipped build artifact, e.g., the built
app/charonbinary or image layers). - Scan-scope noise: path is a workspace cache/artifact directory not intended as deliverable input.
- Repo-tracked: path is under version control (or clearly part of the shipped build artifact, e.g., the built
Decision outcomes:
- If HIGH/CRITICAL are repo-tracked / shipped → remediate by upgrading only the affected components to Trivy’s fixed versions (see Workstreams C/D).
- If HIGH/CRITICAL are only cache/artifact paths → treat as scan-scope noise and align Trivy scan scope to repo contents by excluding those directories (without disabling scanners or suppressing findings).
Workstreams (by role)
Workstream A — Backend (Backend_Dev): Fix go/email-injection
Objective: Ensure no untrusted data can inject additional headers/body content into SMTP DATA.
Implementation direction (minimal + CodeQL-friendly):
- Centralize email header construction (avoid raw
fmt.Sprintf("%s: %s\r\n", ...)with untrusted input). - Reject header values containing
\ror\n(and other control characters if feasible). - Ensure email addresses are created using strict parsing/formatting (
net/mail) and avoid concatenating raw address strings. - Add unit tests that attempt CRLF injection in subject/from/to and assert the send/build path rejects it.
Acceptance criteria:
- CodeQL Go scan shows 0
go/email-injectionfindings. - Backend unit tests cover the rejection paths.
Workstream B — Frontend (Frontend_Dev): Fix js/incomplete-hostname-regexp
Objective: Remove an “incomplete hostname regex” pattern flagged by CodeQL.
Preferred change:
- Replace hostname regex usage with an exact string match (or an anchored + escaped regex like
^link\.example\.com$).
Acceptance criteria:
- CodeQL JS scan shows 0
js/incomplete-hostname-regexpfindings.
Workstream C — Container / embedded binaries (DevOps): Fix Trivy image finding
Objective: Ensure the built image does not ship crowdsec/cscli binaries that embed vulnerable github.com/expr-lang/expr v1.17.2.
Implementation direction:
- If any changes are made to
Dockerfile(including the CrowdSec build stage), rebuild the image (no-cache recommended) before validating. - Prefer bumping the pinned CrowdSec version in
Dockerfileto a release that already depends onexpr >= 1.17.7. - If no suitable CrowdSec release is available, patch the build in the CrowdSec build stage similarly to the existing Caddy stage override (force
expr@1.17.7before building).
Acceptance criteria:
- Trivy image scan reports 0 HIGH/CRITICAL.
Workstream D — Go module upgrades (Backend_Dev + QA_Security): Fix Trivy repo scan findings
Objective: Eliminate Trivy filesystem-scan HIGH/CRITICAL findings without over-upgrading unrelated dependencies.
Implementation direction (conditional; driven by Step 0 triage):
- If Trivy attributes HIGH/CRITICAL to
backend/go.mod/backend/go.sumor to the builtapp/charonbinary:
- Bump only the specific Go modules Trivy flags to Trivy’s fixed versions.
- Run
go mod tidyand ensure builds/tests stay green.
- If Trivy attributes HIGH/CRITICAL only to workspace caches / generated artifacts (e.g.,
.cache/go/pkg/mod/...):
- Treat as scan-scope noise and align Trivy’s filesystem scan scope to repo-tracked content by excluding those directories.
- This is not gate weakening: scanners stay enabled and the project must still achieve 0 HIGH/CRITICAL in Trivy outputs.
Acceptance criteria:
- Trivy scan reports 0 HIGH/CRITICAL.
Validation (VS Code tasks)
Run tasks in this order (only run frontend ones if Workstream B changes anything under frontend/):
- Build: Backend
- Test: Backend with Coverage
- Security: CodeQL All (CI-Aligned)
- Security: Trivy Scan (explicitly verify both filesystem-scan and image-scan outputs are 0 HIGH/CRITICAL)
- Lint: Pre-commit (All Files)
If any changes are made to Dockerfile / CrowdSec build stage:
- Build & Run: Local Docker Image No-Cache (recommended)
- Security: Trivy Scan (re-verify image scan after rebuild)
If frontend/ changes are made:
- Lint: TypeScript Check
- Test: Frontend with Coverage
- Lint: Frontend
Handoff checklist
- Attach updated
codeql-results-*.sarifand Trivy artifacts for both filesystem and image outputs to the QA rerun. - Confirm the QA report’s pass/fail criteria are satisfied (no HIGH/CRITICAL findings).