diff --git a/.grype.yaml b/.grype.yaml index 8e2e1e71..945b8297 100644 --- a/.grype.yaml +++ b/.grype.yaml @@ -4,83 +4,6 @@ # Documentation: https://github.com/anchore/grype#specifying-matches-to-ignore ignore: - # GHSA-69x3-g4r3-p962 / CVE-2026-25793: Nebula ECDSA Signature Malleability - # Severity: HIGH (CVSS 8.1) - # Package: github.com/slackhq/nebula v1.9.7 (embedded in /usr/bin/caddy) - # Status: Cannot upgrade — smallstep/certificates v0.30.0-rc2 still pins nebula v1.9.x - # - # Vulnerability Details: - # - ECDSA signature malleability allows bypassing certificate blocklists - # - Attacker can forge alternate valid P256 ECDSA signatures for revoked - # certificates (CVSSv3: AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N) - # - Only affects configurations using Nebula-based certificate authorities - # (non-default and uncommon in Charon deployments) - # - # Root Cause (Compile-Time Dependency Lock): - # - Caddy is built with caddy-security plugin, which transitively requires - # github.com/smallstep/certificates. That package pins nebula v1.9.x. - # - Checked: smallstep/certificates v0.27.5 → v0.30.0-rc2 all require nebula v1.9.4–v1.9.7. - # The nebula v1.10 API removal breaks compilation in the - # authority/provisioner package; xcaddy build fails with upgrade attempted. - # - Dockerfile caddy-builder stage pins nebula@v1.9.7 (Renovate tracked) with - # an inline comment explaining the constraint (Dockerfile line 247). - # - Fix path: once smallstep/certificates releases a version requiring - # nebula v1.10+, remove the pin and this suppression simultaneously. - # - # Risk Assessment: ACCEPTED (Low exploitability in Charon context) - # - Charon uses standard ACME/Let's Encrypt TLS; Nebula VPN PKI is not - # enabled by default and rarely configured in Charon deployments. - # - Exploiting this requires a valid certificate sharing the same issuer as - # a revoked one — an uncommon and targeted attack scenario. - # - Container-level isolation reduces the attack surface further. - # - # Mitigation (active while suppression is in effect): - # - Monitor smallstep/certificates releases at https://github.com/smallstep/certificates/releases - # - Weekly CI security rebuild flags any new CVEs in the full image. - # - Renovate annotation in Dockerfile (datasource=go depName=github.com/slackhq/nebula) - # will surface the pin for review when xcaddy build becomes compatible. - # - # Review: - # - Reviewed 2026-02-19: smallstep/certificates latest stable remains v0.27.5; - # no release requiring nebula v1.10+ has shipped. Suppression extended 14 days. - # - Reviewed 2026-03-13: smallstep/certificates stable still v0.27.5, extended 30 days. - # - Next review: 2026-04-12. Remove suppression immediately once upstream fixes. - # - # Removal Criteria: - # - smallstep/certificates releases a stable version requiring nebula v1.10+ - # - Update Dockerfile caddy-builder patch to use the new versions - # - Rebuild image, run security scan, confirm suppression no longer needed - # - Remove both this entry and the corresponding .trivyignore entry - # - # References: - # - GHSA: https://github.com/advisories/GHSA-69x3-g4r3-p962 - # - CVE-2026-25793: https://nvd.nist.gov/vuln/detail/CVE-2026-25793 - # - smallstep/certificates: https://github.com/smallstep/certificates/releases - # - Dockerfile pin: caddy-builder stage, line ~247 (go get nebula@v1.9.7) - - vulnerability: GHSA-69x3-g4r3-p962 - package: - name: github.com/slackhq/nebula - version: "v1.9.7" - type: go-module - reason: | - HIGH — ECDSA signature malleability in nebula v1.9.7 embedded in /usr/bin/caddy. - Cannot upgrade: smallstep/certificates v0.27.5 (latest stable as of 2026-03-13) - still requires nebula v1.9.x (verified across v0.27.5–v0.30.0-rc2). Charon does - not use Nebula VPN PKI by default. Risk accepted pending upstream smallstep fix. - Reviewed 2026-03-13: smallstep/certificates stable still v0.27.5, extended 30 days. - expiry: "2026-04-12" # Re-evaluated 2026-03-13: smallstep/certificates stable still v0.27.5, extended 30 days. - - # Action items when this suppression expires: - # 1. Check smallstep/certificates releases: https://github.com/smallstep/certificates/releases - # 2. If a stable version requires nebula v1.10+: - # a. Update Dockerfile caddy-builder: remove the `go get nebula@v1.9.7` pin - # b. Optionally bump smallstep/certificates to the new version - # c. Rebuild Docker image and verify no compile failures - # d. Re-run local security-scan-docker-image and confirm clean result - # e. Remove this suppression entry - # 3. If no fix yet: Extend expiry by 14 days and document justification - # 4. If extended 3+ times: Open upstream issue on smallstep/certificates - # CVE-2026-2673: OpenSSL TLS 1.3 server key exchange group downgrade # Severity: HIGH (CVSS 7.5) # Packages: libcrypto3 3.5.5-r0 and libssl3 3.5.5-r0 (Alpine apk) @@ -153,161 +76,6 @@ ignore: Risk accepted pending Alpine upstream patch. expiry: "2026-04-18" # Initial 30-day review period. See libcrypto3 entry above for action items. - # CVE-2026-33186 / GHSA-p77j-4mvh-x3m3: gRPC-Go authorization bypass via missing leading slash - # Severity: CRITICAL (CVSS 9.1) - # Package: google.golang.org/grpc v1.74.2 (embedded in /usr/local/bin/crowdsec and /usr/local/bin/cscli) - # Status: Fix available at v1.79.3 — waiting on CrowdSec upstream to release with patched grpc - # - # Vulnerability Details: - # - gRPC-Go server path-based authorization (grpc/authz) fails to match deny rules when - # the HTTP/2 :path pseudo-header is missing its leading slash (e.g., "Service/Method" - # instead of "/Service/Method"), allowing a fallback allow-rule to grant access instead. - # - CVSSv3: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - # - # Root Cause (Third-Party Binary): - # - Charon's own grpc dependency is patched to v1.79.3 (updated 2026-03-19). - # - CrowdSec ships grpc v1.74.2 compiled into its binary; Charon has no control over this. - # - This is a server-side vulnerability. CrowdSec uses grpc as a server; Charon uses it - # only as a client (via the Docker SDK). CrowdSec's internal grpc server is not exposed - # to external traffic in a standard Charon deployment. - # - Fix path: once CrowdSec releases a version built with grpc >= v1.79.3, rebuild the - # Docker image (Renovate tracks the CrowdSec version) and remove this suppression. - # - # Risk Assessment: ACCEPTED (Constrained exploitability in Charon context) - # - The vulnerable code path requires an attacker to reach CrowdSec's internal grpc server, - # which is bound to localhost/internal interfaces in the Charon container network. - # - Container-level isolation (no exposed grpc port) significantly limits exposure. - # - Charon does not configure grpc/authz deny rules on CrowdSec's server. - # - # Mitigation (active while suppression is in effect): - # - Monitor CrowdSec releases: https://github.com/crowdsecurity/crowdsec/releases - # - Weekly CI security rebuild flags the moment a fixed CrowdSec image ships. - # - # Review: - # - Reviewed 2026-03-19 (initial suppression): grpc v1.79.3 fix exists; CrowdSec has not - # yet shipped an updated release. Suppression set for 14-day review given fix availability. - # - Next review: 2026-04-02. Remove suppression once CrowdSec ships with grpc >= v1.79.3. - # - # Removal Criteria: - # - CrowdSec releases a version built with google.golang.org/grpc >= v1.79.3 - # - Rebuild Docker image, run security-scan-docker-image, confirm finding is resolved - # - Remove this entry and the corresponding .trivyignore entry simultaneously - # - # References: - # - GHSA-p77j-4mvh-x3m3: https://github.com/advisories/GHSA-p77j-4mvh-x3m3 - # - CVE-2026-33186: https://nvd.nist.gov/vuln/detail/CVE-2026-33186 - # - grpc fix (v1.79.3): https://github.com/grpc/grpc-go/releases/tag/v1.79.3 - # - CrowdSec releases: https://github.com/crowdsecurity/crowdsec/releases - - vulnerability: CVE-2026-33186 - package: - name: google.golang.org/grpc - version: "v1.74.2" - type: go-module - reason: | - CRITICAL — gRPC-Go authorization bypass in grpc v1.74.2 embedded in /usr/local/bin/crowdsec - and /usr/local/bin/cscli. Fix available at v1.79.3 (Charon's own dep is patched); waiting - on CrowdSec upstream to release with patched grpc. CrowdSec's grpc server is not exposed - externally in a standard Charon deployment. Risk accepted pending CrowdSec upstream fix. - Reviewed 2026-03-19: CrowdSec has not yet released with grpc >= v1.79.3. - expiry: "2026-04-02" # 14-day review: fix exists at v1.79.3; check CrowdSec releases. - - # Action items when this suppression expires: - # 1. Check CrowdSec releases: https://github.com/crowdsecurity/crowdsec/releases - # 2. If CrowdSec ships with grpc >= v1.79.3: - # a. Renovate should auto-PR the new CrowdSec version in the Dockerfile - # b. Merge the Renovate PR, rebuild Docker image - # c. Run local security-scan-docker-image and confirm grpc v1.74.2 is gone - # d. Remove this suppression entry and the corresponding .trivyignore entry - # 3. If no fix yet: Extend expiry by 14 days and document justification - # 4. If extended 3+ times: Open an upstream issue on crowdsecurity/crowdsec - - # CVE-2026-33186 (Caddy) — see full justification in the CrowdSec entry above - # Package: google.golang.org/grpc v1.79.1 (embedded in /usr/bin/caddy) - # Status: Fix available at v1.79.3 — waiting on a new Caddy release built with patched grpc - - vulnerability: CVE-2026-33186 - package: - name: google.golang.org/grpc - version: "v1.79.1" - type: go-module - reason: | - CRITICAL — gRPC-Go authorization bypass in grpc v1.79.1 embedded in /usr/bin/caddy. - Fix available at v1.79.3; waiting on Caddy upstream to release a build with patched grpc. - Caddy's grpc server is not exposed externally in a standard Charon deployment. - Risk accepted pending Caddy upstream fix. Reviewed 2026-03-19: no Caddy release with grpc >= v1.79.3 yet. - expiry: "2026-04-02" # 14-day review: fix exists at v1.79.3; check Caddy releases. - - # Action items when this suppression expires: - # 1. Check Caddy releases: https://github.com/caddyserver/caddy/releases - # (or the custom caddy-builder in the Dockerfile for caddy-security plugin) - # 2. If a new Caddy build ships with grpc >= v1.79.3: - # a. Update the Caddy version pin in the Dockerfile caddy-builder stage - # b. Rebuild Docker image and run local security-scan-docker-image - # c. Remove this suppression entry and the corresponding .trivyignore entry - # 3. If no fix yet: Extend expiry by 14 days and document justification - # 4. If extended 3+ times: Open an issue on caddyserver/caddy - - # GHSA-479m-364c-43vc: goxmldsig XML signature validation bypass (loop variable capture) - # Severity: HIGH (CVSS 7.5) - # Package: github.com/russellhaering/goxmldsig v1.5.0 (embedded in /usr/bin/caddy) - # Status: Fix available at v1.6.0 — waiting on a new Caddy release built with patched goxmldsig - # - # Vulnerability Details: - # - Loop variable capture in validateSignature causes the signature reference to always - # point to the last element in SignedInfo.References; an attacker can substitute signed - # element content and bypass XML signature integrity validation (CWE-347, CWE-682). - # - CVSSv3: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N - # - # Root Cause (Third-Party Binary): - # - Charon does not use goxmldsig directly. The package is compiled into /usr/bin/caddy - # via the caddy-security plugin's SAML/SSO support. - # - Fix path: once Caddy (or the caddy-security plugin) releases a build with - # goxmldsig >= v1.6.0, rebuild the Docker image and remove this suppression. - # - # Risk Assessment: ACCEPTED (Low exploitability in default Charon context) - # - The vulnerability only affects SAML/XML signature validation workflows. - # - Charon does not enable or configure SAML-based SSO in its default setup. - # - Exploiting this requires an active SAML integration, which is non-default. - # - # Mitigation (active while suppression is in effect): - # - Monitor caddy-security plugin releases: https://github.com/greenpau/caddy-security/releases - # - Monitor Caddy releases: https://github.com/caddyserver/caddy/releases - # - Weekly CI security rebuild flags the moment a fixed image ships. - # - # Review: - # - Reviewed 2026-03-19 (initial suppression): goxmldsig v1.6.0 fix exists; Caddy has not - # yet shipped with the updated dep. Set 14-day review given fix availability. - # - Next review: 2026-04-02. Remove suppression once Caddy ships with goxmldsig >= v1.6.0. - # - # Removal Criteria: - # - Caddy (or caddy-security plugin) releases a build with goxmldsig >= v1.6.0 - # - Rebuild Docker image, run security-scan-docker-image, confirm finding is resolved - # - Remove this entry and the corresponding .trivyignore entry simultaneously - # - # References: - # - GHSA-479m-364c-43vc: https://github.com/advisories/GHSA-479m-364c-43vc - # - goxmldsig v1.6.0 fix: https://github.com/russellhaering/goxmldsig/releases/tag/v1.6.0 - # - caddy-security plugin: https://github.com/greenpau/caddy-security/releases - - vulnerability: GHSA-479m-364c-43vc - package: - name: github.com/russellhaering/goxmldsig - version: "v1.5.0" - type: go-module - reason: | - HIGH — XML signature validation bypass in goxmldsig v1.5.0 embedded in /usr/bin/caddy. - Fix available at v1.6.0; waiting on Caddy upstream to release a build with patched goxmldsig. - Charon does not configure SAML-based SSO by default; the vulnerable XML signature path - is not reachable in a standard deployment. Risk accepted pending Caddy upstream fix. - Reviewed 2026-03-19: no Caddy release with goxmldsig >= v1.6.0 yet. - expiry: "2026-04-02" # 14-day review: fix exists at v1.6.0; check Caddy/caddy-security releases. - - # Action items when this suppression expires: - # 1. Check caddy-security releases: https://github.com/greenpau/caddy-security/releases - # 2. If a new build ships with goxmldsig >= v1.6.0: - # a. Update the Caddy version pin in the Dockerfile caddy-builder stage if needed - # b. Rebuild Docker image and run local security-scan-docker-image - # c. Remove this suppression entry and the corresponding .trivyignore entry - # 3. If no fix yet: Extend expiry by 14 days and document justification - # GHSA-6g7g-w4f8-9c9x: buger/jsonparser Delete panic on malformed JSON (DoS) # Severity: HIGH (CVSS 7.5) # Package: github.com/buger/jsonparser v1.1.1 (embedded in /usr/local/bin/crowdsec and /usr/local/bin/cscli) diff --git a/SECURITY.md b/SECURITY.md index 96c6c2bc..ec4df8b2 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -27,49 +27,7 @@ public disclosure. ## Known Vulnerabilities -### [CRITICAL] CVE-2025-68121 · Go Stdlib Critical in CrowdSec Bundled Binaries - -| Field | Value | -|--------------|-------| -| **ID** | CVE-2025-68121 (see also CHARON-2025-001) | -| **Severity** | Critical | -| **Status** | Awaiting Upstream | - -**What** -A critical Go standard library vulnerability affects CrowdSec binaries bundled in the Charon -container image. The binaries were compiled against Go 1.25.6, which contains this flaw. -Charon's own application code, compiled with Go 1.26.1, is unaffected. - -**Who** - -- Discovered by: Automated scan (Grype) -- Reported: 2026-03-20 -- Affects: CrowdSec Agent component within the container; not directly exposed through Charon's - primary application interface - -**Where** - -- Component: CrowdSec Agent (bundled `cscli` and `crowdsec` binaries) -- Versions affected: Charon container images with CrowdSec binaries compiled against Go < 1.25.7 - -**When** - -- Discovered: 2026-03-20 -- Disclosed (if public): Not yet publicly disclosed -- Target fix: When `golang:1.26.2-alpine` is published on Docker Hub - -**How** -The vulnerability resides entirely within CrowdSec's compiled binary artifacts. Exploitation -is limited to the CrowdSec agent's internal execution paths, which are not externally exposed -through Charon's API or network interface. - -**Planned Remediation** -`golang:1.26.2-alpine` is not yet available on Docker Hub. The `GO_VERSION` ARG has been -reverted to `1.26.1` (the latest published image) until `1.26.2` is released. Once -`golang:1.26.2-alpine` is available, bumping `GO_VERSION` to `1.26.2` and rebuilding the image -will also resolve CVE-2026-25679 (High) and CVE-2025-61732 (High) tracked under CHARON-2025-001. - ---- +Last reviewed: 2026-03-24 ### [HIGH] CVE-2026-2673 · OpenSSL TLS 1.3 Key Exchange Group Downgrade @@ -115,13 +73,135 @@ available, update the pinned `ALPINE_IMAGE` digest in the Dockerfile, or add an --- -### [HIGH] CHARON-2025-001 · CrowdSec Bundled Binaries — Go Stdlib CVEs +### [MEDIUM] CVE-2025-60876 · BusyBox wget HTTP Request Smuggling + +| Field | Value | +|--------------|-------| +| **ID** | CVE-2025-60876 | +| **Severity** | Medium · 6.5 | +| **Status** | Awaiting Upstream | + +**What** +BusyBox wget through 1.37 accepts raw CR/LF and other C0 control bytes in the HTTP +request-target, allowing request line splitting and header injection (CWE-284). + +**Who** + +- Discovered by: Automated scan (Grype) +- Reported: 2026-03-24 +- Affects: Container runtime environment; Charon does not invoke busybox wget in application logic + +**Where** + +- Component: Alpine 3.23.3 base image (`busybox` 1.37.0-r30) +- Versions affected: All Charon images using Alpine 3.23.3 with busybox < patched version + +**When** + +- Discovered: 2026-03-24 +- Disclosed (if public): Not yet publicly disclosed with fix +- Target fix: When Alpine Security publishes a patched busybox APK + +**How** +The vulnerable wget applet would need to be manually invoked inside the container with +attacker-controlled URLs. Charon's application logic does not use busybox wget. EPSS score is +0.00064 (0.20 percentile), indicating extremely low exploitation probability. + +**Planned Remediation** +Monitor Alpine 3.23 for a patched busybox APK. No immediate action required. Practical risk to +Charon users is negligible since the vulnerable code path is not exercised. + +--- + +### [LOW] CVE-2026-26958 · edwards25519 MultiScalarMult Invalid Results + +| Field | Value | +|--------------|-------| +| **ID** | CVE-2026-26958 (GHSA-fw7p-63qq-7hpr) | +| **Severity** | Low · 1.7 | +| **Status** | Awaiting Upstream | + +**What** +`filippo.io/edwards25519` v1.1.0 `MultiScalarMult` produces invalid results or undefined +behavior if the receiver is not the identity point. Fix available at v1.1.1 but requires +CrowdSec to rebuild. + +**Who** + +- Discovered by: Automated scan (Grype) +- Reported: 2026-03-24 +- Affects: CrowdSec Agent component within the container; not directly exposed through Charon's + primary application interface + +**Where** + +- Component: CrowdSec Agent (bundled `cscli` and `crowdsec` binaries) +- Versions affected: CrowdSec builds using `filippo.io/edwards25519` < v1.1.1 + +**When** + +- Discovered: 2026-03-24 +- Disclosed (if public): Public +- Target fix: When CrowdSec releases a build with updated dependency + +**How** +This is a rarely used advanced API within the edwards25519 library. CrowdSec does not directly +expose MultiScalarMult to external input. EPSS score is 0.00018 (0.04 percentile). + +**Planned Remediation** +Awaiting CrowdSec upstream release with updated dependency. No action available for Charon +maintainers. + +--- + +## Patched Vulnerabilities + +### ✅ [CRITICAL] CVE-2025-68121 · Go Stdlib Critical in CrowdSec Bundled Binaries + +| Field | Value | +|--------------|-------| +| **ID** | CVE-2025-68121 (see also CHARON-2025-001) | +| **Severity** | Critical | +| **Patched** | 2026-03-24 | + +**What** +A critical Go standard library vulnerability affects CrowdSec binaries bundled in the Charon +container image. The binaries were compiled against Go 1.25.6, which contains this flaw. +Charon's own application code, compiled with Go 1.26.1, is unaffected. + +**Who** + +- Discovered by: Automated scan (Grype) +- Reported: 2026-03-20 + +**Where** + +- Component: CrowdSec Agent (bundled `cscli` and `crowdsec` binaries) +- Versions affected: Charon container images with CrowdSec binaries compiled against Go < 1.25.7 + +**When** + +- Discovered: 2026-03-20 +- Patched: 2026-03-24 +- Time to patch: 4 days + +**How** +The vulnerability resides entirely within CrowdSec's compiled binary artifacts. Exploitation +is limited to the CrowdSec agent's internal execution paths, which are not externally exposed +through Charon's API or network interface. + +**Resolution** +CrowdSec binaries now compiled with Go 1.26.1 (was 1.25.6). + +--- + +### ✅ [HIGH] CHARON-2025-001 · CrowdSec Bundled Binaries — Go Stdlib CVEs | Field | Value | |--------------|-------| | **ID** | CHARON-2025-001 (aliases: CVE-2025-58183, CVE-2025-58186, CVE-2025-58187, CVE-2025-61729, CVE-2026-25679, CVE-2025-61732, CVE-2026-27142, CVE-2026-27139) | | **Severity** | High · (preliminary, CVSS scores pending upstream confirmation) | -| **Status** | Awaiting Upstream | +| **Patched** | 2026-03-24 | **What** Multiple CVEs in Go standard library packages continue to accumulate in CrowdSec binaries bundled @@ -135,8 +215,6 @@ Charon's own application code is unaffected. - Discovered by: Automated scan (Trivy, Grype) - Reported: 2025-12-01 (original cluster); expanded 2026-03-20 -- Affects: CrowdSec Agent component within the container; not directly exposed through Charon's - primary application interface **Where** @@ -146,29 +224,26 @@ Charon's own application code is unaffected. **When** - Discovered: 2025-12-01 -- Disclosed (if public): Not yet publicly disclosed -- Target fix: When `golang:1.26.2-alpine` is published on Docker Hub +- Patched: 2026-03-24 +- Time to patch: 114 days **How** The CVEs reside entirely within CrowdSec's compiled binaries and cover HTTP/2, TLS, and archive processing paths that are not invoked by Charon's core application logic. The relevant network interfaces are not externally exposed via Charon's API surface. -**Planned Remediation** -`golang:1.26.2-alpine` is not yet available on Docker Hub. The `GO_VERSION` ARG has been -reverted to `1.26.1` (the latest published image) until `1.26.2` is released. Once available, -bumping `GO_VERSION` to `1.26.2` and rebuilding the image will resolve the entire alias cluster. -CVE-2025-68121 (Critical severity, same root cause) is tracked separately above. +**Resolution** +CrowdSec binaries now compiled with Go 1.26.1. --- -### [MEDIUM] CVE-2026-27171 · zlib CPU Exhaustion via Infinite Loop in CRC Combine Functions +### ✅ [MEDIUM] CVE-2026-27171 · zlib CPU Exhaustion via Infinite Loop in CRC Combine Functions | Field | Value | |--------------|-------| | **ID** | CVE-2026-27171 | | **Severity** | Medium · 5.5 (NVD) / 2.9 (MITRE) | -| **Status** | Awaiting Upstream | +| **Patched** | 2026-03-24 | **What** zlib before 1.3.2 allows unbounded CPU consumption (denial of service) via the `crc32_combine64` @@ -180,8 +255,6 @@ loop with no termination condition when given a specially crafted input, causing - Discovered by: 7aSecurity audit (commissioned by OSTIF) - Reported: 2026-02-17 -- Affects: Any component in the container that calls `crc32_combine`-family functions with - attacker-controlled input; not directly exposed through Charon's application interface **Where** @@ -190,25 +263,20 @@ loop with no termination condition when given a specially crafted input, causing **When** -- Discovered: 2026-02-17 (NVD published 2026-02-17) -- Disclosed (if public): 2026-02-17 -- Target fix: When Alpine 3.23 publishes a patched `zlib` APK (requires zlib 1.3.2) +- Discovered: 2026-02-17 +- Patched: 2026-03-24 +- Time to patch: 35 days **How** Exploitation requires local access (CVSS vector `AV:L`) and the ability to pass a crafted value to the `crc32_combine`-family functions. This code path is not invoked by Charon's reverse proxy or backend API. The vulnerability is non-blocking under the project's CI severity policy. -**Planned Remediation** -Monitor for a patched Alpine APK. Once -available, update the pinned `ALPINE_IMAGE` digest in the Dockerfile, or add an explicit -`RUN apk upgrade --no-cache zlib` to the runtime stage. Remove the `.trivyignore` entry at -that time. +**Resolution** +Alpine now ships zlib 1.3.2-r0 (fix threshold was 1.3.2). --- -## Patched Vulnerabilities - ### ✅ [HIGH] CHARON-2026-001 · Debian Base Image CVE Cluster | Field | Value | @@ -565,4 +633,4 @@ We recognize security researchers who help improve Charon: --- -**Last Updated**: 2026-03-20 +**Last Updated**: 2026-03-24 diff --git a/docs/reports/qa_report.md b/docs/reports/qa_report.md index 22901a08..b8a1fc0a 100644 --- a/docs/reports/qa_report.md +++ b/docs/reports/qa_report.md @@ -1,609 +1,322 @@ -# QA Security Audit Report — CWE-614 Remediation - -**Date:** 2026-03-21 -**Scope:** `backend/internal/api/handlers/auth_handler.go` — removal of `secure = false` branch from `setSecureCookie` -**Audited by:** QA Security Agent - ---- - -## Scope - -Backend-only change. File audited: - -| File | Change Type | -|------|-------------| -| `backend/internal/api/handlers/auth_handler.go` | Modified — `secure = false` branch removed; `Secure` always `true` | -| `backend/internal/api/handlers/auth_handler_test.go` | Modified — all `TestSetSecureCookie_*` assertions updated to `assert.True(t, cookie.Secure)` | - ---- - -## 1. Test Results - -| Metric | Value | Gate | Status | -|---|---|---|---| -| Statement coverage | 88.0% | ≥ 87% | ✅ PASS | -| Line coverage | 88.2% | ≥ 87% | ✅ PASS | -| Test failures | 0 | 0 | ✅ PASS | - -All `TestSetSecureCookie_*` variants assert `cookie.Secure == true` unconditionally, correctly reflecting the remediated behaviour. - ---- - -## 2. Lint Results - -**Tool:** `golangci-lint` (fast config — staticcheck, govet, errcheck, ineffassign, unused) - -**Result:** `0 issues` — ✅ PASS - ---- - -## 3. Pre-commit Hooks - -**Tool:** Lefthook v2.1.4 - -| Hook | Result | -|---|---| -| check-yaml | ✅ PASS | -| actionlint | ✅ PASS | -| end-of-file-fixer | ✅ PASS | -| trailing-whitespace | ✅ PASS | -| dockerfile-check | ✅ PASS | -| shellcheck | ✅ PASS | - -Go-specific hooks (`go-vet`, `golangci-lint-fast`) were skipped — no staged files. These were validated directly via `make lint-fast`. - ---- - -## 4. Trivy Security Scan - -**Tool:** Trivy v0.52.2 - -### New Vulnerabilities Introduced by This Change - -**None.** Zero HIGH or CRITICAL vulnerabilities attributable to the CWE-614 remediation. - -### Pre-existing Baseline Finding (unrelated) - -| ID | Severity | Type | Description | -|---|---|---|---| -| DS002 | HIGH | Dockerfile misconfiguration | Container runs as root — pre-existing, not introduced by this change | - ---- - -## 5. CWE-614 Verification - -### Pattern Search: `secure = false` in handlers package - -``` -grep -rn "secure = false" /projects/Charon/backend/ -``` - -**Result:** 0 matches — ✅ CLEARED - -### Pattern Search: Inline CodeQL suppression - -``` -grep -rn "codeql[go/cookie-secure-not-set]" /projects/Charon/backend/ -``` - -**Result:** 0 matches — ✅ CLEARED - -### `setSecureCookie` Implementation - -The function unconditionally passes `true` as the `secure` argument to `c.SetCookie`: - -```go -c.SetCookie( - name, // name - value, // value - maxAge, // maxAge in seconds - "/", // path - domain, // domain (empty = current host) - true, // secure ← always true, no conditional branch - true, // httpOnly -) -``` - -All test cases (`TestSetSecureCookie_HTTPS_Strict`, `_HTTP_Lax`, `_HTTP_Loopback_Insecure`, -`_ForwardedHTTPS_*`, `_HTTP_PrivateIP_Insecure`, `_HTTP_10Network_Insecure`, -`_HTTP_172Network_Insecure`) assert `cookie.Secure == true`. - ---- - -## Summary - -| Check | Result | Notes | -|---|---|---| -| Backend unit tests | ✅ PASS | 0 failures, 88.0% coverage (gate: 87%) | -| Lint | ✅ PASS | 0 issues | -| Pre-commit hooks | ✅ PASS | All 6 active hooks passed | -| Trivy | ✅ PASS | No new HIGH/CRITICAL vulns | -| `secure = false` removed | ✅ CLEARED | 0 matches in handlers package | -| CodeQL suppression removed | ✅ CLEARED | 0 matches in handlers package | - ---- - -## Overall: ✅ PASS - -The CWE-614 remediation is complete and correct. All cookies set by `setSecureCookie` now unconditionally carry `Secure = true`. No regressions, no new security findings, and coverage remains above the required threshold. - - ---- - - - -# QA Audit Report — PR-1: Allow Empty Value in UpdateSetting - -**Date:** 2026-03-17 -**Scope:** Remove `binding:"required"` from `Value` field in `UpdateSettingRequest` -**File:** `backend/internal/api/handlers/settings_handler.go` - ---- - -# QA Security Audit Report — Rate Limit CI Fix - -**Audited by**: QA Security Auditor -**Date**: 2026-03-17 -**Spec reference**: `docs/plans/rate_limit_ci_fix_spec.md` -**Files audited**: -- `scripts/rate_limit_integration.sh` -- `Dockerfile` (GeoIP section, non-CI path) -- `.github/workflows/rate-limit-integration.yml` - ---- - -## Pre-Commit Check Results - -| Check | Command | Result | -|-------|---------|--------| -| Bash syntax | `bash -n scripts/rate_limit_integration.sh` | ✅ PASS (exit 0) | -| Pre-commit hooks | `lefthook run pre-commit` (project uses lefthook; no `.pre-commit-config.yaml`) | ✅ PASS — all 6 hooks passed: `check-yaml`, `actionlint`, `end-of-file-fixer`, `trailing-whitespace`, `dockerfile-check`, `shellcheck` | -| Caddy admin API trailing slash (workflow) | `grep -n "2119" .github/workflows/rate-limit-integration.yml` | ✅ PASS — line 71 references `/config/` (trailing slash present) | -| Caddy admin API trailing slash (script) | All 6 occurrences of `localhost:2119/config` in script | ✅ PASS — all use `/config/` | - ---- - -## Security Focus Area Results - -### 1. Credential Handling — `TMP_COOKIE` - -**`mktemp` usage**: `TMP_COOKIE=$(mktemp)` at line 208. Creates a file in `/tmp` with `600` permissions via the OS. ✅ SECURE. - -**Removal on exit**: The `cleanup()` function at line 103 removes the file with `rm -f "${TMP_COOKIE:-}"`. However, `cleanup` is only registered via explicit calls — there is **no `trap cleanup EXIT`**. Only `trap on_failure ERR` is registered (line 108). - -**Gap**: On 5 early `exit 1` paths after line 208 (login failure L220, auth failure L251, Caddy readiness failure L282, security config failure L299, and handler verification failure L316), `cleanup` is never called. The cookie file is left in `/tmp`. - -**Severity**: LOW — The cookie contains session credentials for a localhost test server (`ratelimit@example.local` / `password123`, non-production). CI runners are ephemeral and auto-cleaned. Local runs will leave a `/tmp/tmp.XXXXXX` file until next reboot or manual cleanup. - -**Note**: The exit at line 386 (inside the 429 enforcement failure block) intentionally skips cleanup to leave containers running for manual inspection. This is by design and acceptable. - -**Recommendation**: Add `trap cleanup EXIT` immediately after `trap on_failure ERR` (line 109) to ensure the cookie file is always removed. - ---- - -### 2. `curl` — Sensitive Values in Command-Line Arguments - -Cookie file path is passed via `-c ${TMP_COOKIE}` and `-b ${TMP_COOKIE}` (unquoted). No credentials, tokens, or API keys are passed as command-line arguments. All authentication is via the cookie file (read/write by path), which is the correct pattern — cookie values never appear in `ps` output. - -**Finding (LOW)**: `${TMP_COOKIE}` is unquoted in all 6 curl invocations. `mktemp` on Linux produces paths of the form `/tmp/tmp.XXXXXX` which never contain spaces or shell metacharacters under default `$TMPDIR`. However, under a non-standard `$TMPDIR` (e.g., `/tmp/my dir/`) this would break. This is a portability issue, not a security issue. - -**Recommendation**: Quote `"${TMP_COOKIE}"` in all curl invocations. - ---- - -### 3. Shell Injection - -All interpolated values in curl `-d` payloads are either: -- Script-level constants (`RATE_LIMIT_REQUESTS=3`, `RATE_LIMIT_WINDOW_SEC=10`, `RATE_LIMIT_BURST=1`, `TEST_DOMAIN=ratelimit.local`, `BACKEND_CONTAINER=ratelimit-backend`) -- Values derived from API responses stored in double-quoted variables (`"$CREATE_RESP"`, `"$SEC_CONFIG_RESP"`) - -No shell injection vector exists. All heredoc expansions (`cat < sbom-generated.json`. - -### Delete or Gitignore `.trivy_logs/charon_binary` - -The 23MB stale binary `.trivy_logs/charon_binary` (go1.25.4, Nov 2025) is a Trivy scan artifact causing several Critical/High CVE findings. Add `.trivy_logs/*.binary` or the whole `.trivy_logs/` directory to `.gitignore`. +| Field | Value | +|------------------|-------| +| **Previous Severity** | Medium | +| **Resolution** | Alpine now ships `zlib` 1.3.2-r0 (fix threshold: 1.3.2) | +| **Verified** | Not detected in Grype scan; zlib 1.3.2-r0 confirmed in SBOM | --- -## 5. Summary +### CVE-2026-33186 — gRPC-Go Authorization Bypass (RESOLVED) -| # | Finding | Severity | False Positive? | Action Required | -|---|---|---|---|---| -| 1 | CVE-2025-68121 in `.trivy_logs/charon_binary` + `backend/bin/*` | **Critical** | No | Rebuild binaries with go1.26.1; delete stale `.trivy_logs/charon_binary` | -| 2 | CVE-2026-33186 in Charon source | — | N/A | **Already fixed** (v1.79.3) | -| 3 | CVE-2026-33186 in CrowdSec/Caddy binaries | High | Yes (for Charon) | Upgrade CrowdSec and Caddy Docker image tags | -| 4 | GHSA-479m-364c-43vc (`goxmldsig`) | Medium | **Yes** | Upgrade Caddy Docker image | -| 5 | GHSA-6g7g-w4f8-9c9x (`jsonparser`) | Medium | **Yes** | Upgrade CrowdSec Docker image | -| 6 | GHSA-jqcq-xjh3-6g23 (`pgproto3/v2`) | Medium | **Yes** | Upgrade CrowdSec Docker image | -| 7 | High stdlib CVEs in `backend/bin/` binaries | High | No | Rebuild with go1.26.1 | -| 8 | Python venv packages | Medium | No (dev only) | `pip upgrade` in local envs | -| 9 | Module cache false positives | Critical–High | **Yes** | Exclude `.cache/` from `grype dir:.` | -| 10 | Stale `sbom-generated.json` | — | Yes | Delete or regenerate | +| Field | Value | +|------------------|-------| +| **Previous Severity** | Critical | +| **Packages** | `google.golang.org/grpc` v1.74.2 (CrowdSec), v1.79.1 (Caddy) | +| **Resolution** | Upstream releases now include patched gRPC (>= v1.79.3) | +| **Verified** | Not detected in Grype scan; ignore rule present but no match | +--- + +### GHSA-69x3-g4r3-p962 / CVE-2026-25793 — Nebula ECDSA Malleability (RESOLVED) + +| Field | Value | +|------------------|-------| +| **Previous Severity** | High | +| **Package** | `github.com/slackhq/nebula` v1.9.7 in Caddy | +| **Resolution** | Caddy now ships with nebula >= v1.10.3 | +| **Verified** | Not detected in Grype scan; Trivy image report from Feb 25 had this but current build does not | + +> **Note**: The stale Trivy image report (`trivy-image-report.json`, dated 2026-02-25) still +> shows CVE-2026-25793. This report predates the current build and should be regenerated. + +--- + +### GHSA-479m-364c-43vc — goxmldsig XML Signature Bypass (RESOLVED) + +| Field | Value | +|------------------|-------| +| **Previous Severity** | High | +| **Package** | `github.com/russellhaering/goxmldsig` v1.5.0 in Caddy | +| **Resolution** | Caddy now ships with goxmldsig >= v1.6.0 | +| **Verified** | Not detected in Grype scan; ignore rule present but no match | + +--- + +## CodeQL Analysis + +### go/cookie-secure-not-set — FALSE POSITIVE + +| Field | Value | +|------------------|-------| +| **Severity** | Medium (CodeQL) | +| **File** | `backend/internal/api/handlers/auth_handler.go:152` | +| **Classification** | FALSE POSITIVE (stale SARIF) | + +**Finding**: CodeQL reports "Cookie does not set Secure attribute to true" at line 152. + +**Verification**: The `setSecureCookie` function at line 148-156 calls `c.SetCookie()` +with `secure: true` (6th positional argument). The Secure attribute IS set correctly. +This SARIF was generated from a previous code version and does not reflect the current +source. **The CodeQL SARIF files should be regenerated.** + +### JavaScript / JS + +No findings. Both `codeql-results-javascript.sarif` and `codeql-results-js.sarif` contain +0 results. + +--- + +## GORM Security Scanner + +| Metric | Value | +|------------|-------| +| **Result** | PASSED | +| **Files** | 43 Go files (2,396 lines) | +| **Critical** | 0 | +| **High** | 0 | +| **Medium** | 0 | +| **Info** | 2 (missing indexes on foreign keys in `UserPermittedHost`) | + +The 2 informational suggestions (`UserID` and `ProxyHostID` missing `gorm:"index"` in +`backend/internal/models/user.go:130-131`) are performance recommendations, not security +issues. They do not block this audit. + +--- + +## CI vs Local Scan Discrepancy + +The CI reported **3 Critical, 5 High, 1 Medium**. The local scan on the freshly built +image reports **0 Critical, 0 High, 4 Medium, 2 Low** (active) plus **4 High** (ignored). + +**Root causes for the discrepancy:** + +1. **Resolved vulnerabilities**: 3 Critical and 4 High findings were resolved by Go 1.26.1 + compilation and upstream Caddy/CrowdSec dependency updates since the CI image was built. +2. **Grype ignore rules**: The local scan applies documented risk acceptance rules that + suppress 4 High findings in third-party binaries. CI (Trivy) does not use these rules. +3. **Stale CI artifacts**: The `trivy-image-report.json` dates from 2026-02-25 and does + not reflect the current image state. The `codeql-results-go.sarif` references code that + has since been fixed. + +--- + +## Recommended Actions + +### Immediate (This Sprint) + +1. **Update SECURITY.md**: Move CVE-2025-68121, CHARON-2025-001, and CVE-2026-27171 to + a "Patched Vulnerabilities" section. Add CVE-2025-60876 and CVE-2026-26958 as new + known vulnerabilities. + +2. **Regenerate stale scan artifacts**: Re-run Trivy image scan and CodeQL analysis to + produce current SARIF/JSON files. The existing files predate fixes and produce + misleading CI results. + +3. **Clean up Grype ignore rules**: Remove ignore entries for vulnerabilities that are + no longer detected (CVE-2026-33186, GHSA-69x3-g4r3-p962, GHSA-479m-364c-43vc). + Stale ignore rules obscure the actual security posture. + +### Next Release + +4. **Monitor Alpine APK updates**: Watch for patched `busybox` (CVE-2025-60876) and + `openssl` (CVE-2026-2673) packages in Alpine 3.23. + +5. **Monitor CrowdSec releases**: Watch for CrowdSec builds with updated + `filippo.io/edwards25519` >= v1.1.1, `buger/jsonparser` >= v1.1.2, and + `pgx/v5` migration (replacing pgproto3/v2). + +6. **Monitor Go 1.26.2-alpine**: When available, bump `GO_VERSION` to pick up any + remaining stdlib patches. + +### Informational (Non-Blocking) + +7. **GORM indexes**: Consider adding `gorm:"index"` to `UserID` and `ProxyHostID` in + `UserPermittedHost` for query performance. + +--- + +## Gotify Token Review + +Verified: No Gotify application tokens appear in scan output, log artifacts, test results, +API examples, or URL query parameters. All diagnostic output is clean. + +--- + +## Conclusion + +The Charon container image security posture has materially improved. Six previously known +vulnerabilities are now resolved through Go toolchain and dependency updates. The remaining +active findings are medium/low severity, reside in Alpine base packages and CrowdSec +third-party binaries, and have no available fixes. No vulnerabilities exist in Charon's +own application code. GORM and CodeQL scans confirm the backend code is clean. diff --git a/docs/reports/qa_report_2026-03-21_cwe614.md b/docs/reports/qa_report_2026-03-21_cwe614.md new file mode 100644 index 00000000..22901a08 --- /dev/null +++ b/docs/reports/qa_report_2026-03-21_cwe614.md @@ -0,0 +1,609 @@ +# QA Security Audit Report — CWE-614 Remediation + +**Date:** 2026-03-21 +**Scope:** `backend/internal/api/handlers/auth_handler.go` — removal of `secure = false` branch from `setSecureCookie` +**Audited by:** QA Security Agent + +--- + +## Scope + +Backend-only change. File audited: + +| File | Change Type | +|------|-------------| +| `backend/internal/api/handlers/auth_handler.go` | Modified — `secure = false` branch removed; `Secure` always `true` | +| `backend/internal/api/handlers/auth_handler_test.go` | Modified — all `TestSetSecureCookie_*` assertions updated to `assert.True(t, cookie.Secure)` | + +--- + +## 1. Test Results + +| Metric | Value | Gate | Status | +|---|---|---|---| +| Statement coverage | 88.0% | ≥ 87% | ✅ PASS | +| Line coverage | 88.2% | ≥ 87% | ✅ PASS | +| Test failures | 0 | 0 | ✅ PASS | + +All `TestSetSecureCookie_*` variants assert `cookie.Secure == true` unconditionally, correctly reflecting the remediated behaviour. + +--- + +## 2. Lint Results + +**Tool:** `golangci-lint` (fast config — staticcheck, govet, errcheck, ineffassign, unused) + +**Result:** `0 issues` — ✅ PASS + +--- + +## 3. Pre-commit Hooks + +**Tool:** Lefthook v2.1.4 + +| Hook | Result | +|---|---| +| check-yaml | ✅ PASS | +| actionlint | ✅ PASS | +| end-of-file-fixer | ✅ PASS | +| trailing-whitespace | ✅ PASS | +| dockerfile-check | ✅ PASS | +| shellcheck | ✅ PASS | + +Go-specific hooks (`go-vet`, `golangci-lint-fast`) were skipped — no staged files. These were validated directly via `make lint-fast`. + +--- + +## 4. Trivy Security Scan + +**Tool:** Trivy v0.52.2 + +### New Vulnerabilities Introduced by This Change + +**None.** Zero HIGH or CRITICAL vulnerabilities attributable to the CWE-614 remediation. + +### Pre-existing Baseline Finding (unrelated) + +| ID | Severity | Type | Description | +|---|---|---|---| +| DS002 | HIGH | Dockerfile misconfiguration | Container runs as root — pre-existing, not introduced by this change | + +--- + +## 5. CWE-614 Verification + +### Pattern Search: `secure = false` in handlers package + +``` +grep -rn "secure = false" /projects/Charon/backend/ +``` + +**Result:** 0 matches — ✅ CLEARED + +### Pattern Search: Inline CodeQL suppression + +``` +grep -rn "codeql[go/cookie-secure-not-set]" /projects/Charon/backend/ +``` + +**Result:** 0 matches — ✅ CLEARED + +### `setSecureCookie` Implementation + +The function unconditionally passes `true` as the `secure` argument to `c.SetCookie`: + +```go +c.SetCookie( + name, // name + value, // value + maxAge, // maxAge in seconds + "/", // path + domain, // domain (empty = current host) + true, // secure ← always true, no conditional branch + true, // httpOnly +) +``` + +All test cases (`TestSetSecureCookie_HTTPS_Strict`, `_HTTP_Lax`, `_HTTP_Loopback_Insecure`, +`_ForwardedHTTPS_*`, `_HTTP_PrivateIP_Insecure`, `_HTTP_10Network_Insecure`, +`_HTTP_172Network_Insecure`) assert `cookie.Secure == true`. + +--- + +## Summary + +| Check | Result | Notes | +|---|---|---| +| Backend unit tests | ✅ PASS | 0 failures, 88.0% coverage (gate: 87%) | +| Lint | ✅ PASS | 0 issues | +| Pre-commit hooks | ✅ PASS | All 6 active hooks passed | +| Trivy | ✅ PASS | No new HIGH/CRITICAL vulns | +| `secure = false` removed | ✅ CLEARED | 0 matches in handlers package | +| CodeQL suppression removed | ✅ CLEARED | 0 matches in handlers package | + +--- + +## Overall: ✅ PASS + +The CWE-614 remediation is complete and correct. All cookies set by `setSecureCookie` now unconditionally carry `Secure = true`. No regressions, no new security findings, and coverage remains above the required threshold. + + +--- + + + +# QA Audit Report — PR-1: Allow Empty Value in UpdateSetting + +**Date:** 2026-03-17 +**Scope:** Remove `binding:"required"` from `Value` field in `UpdateSettingRequest` +**File:** `backend/internal/api/handlers/settings_handler.go` + +--- + +# QA Security Audit Report — Rate Limit CI Fix + +**Audited by**: QA Security Auditor +**Date**: 2026-03-17 +**Spec reference**: `docs/plans/rate_limit_ci_fix_spec.md` +**Files audited**: +- `scripts/rate_limit_integration.sh` +- `Dockerfile` (GeoIP section, non-CI path) +- `.github/workflows/rate-limit-integration.yml` + +--- + +## Pre-Commit Check Results + +| Check | Command | Result | +|-------|---------|--------| +| Bash syntax | `bash -n scripts/rate_limit_integration.sh` | ✅ PASS (exit 0) | +| Pre-commit hooks | `lefthook run pre-commit` (project uses lefthook; no `.pre-commit-config.yaml`) | ✅ PASS — all 6 hooks passed: `check-yaml`, `actionlint`, `end-of-file-fixer`, `trailing-whitespace`, `dockerfile-check`, `shellcheck` | +| Caddy admin API trailing slash (workflow) | `grep -n "2119" .github/workflows/rate-limit-integration.yml` | ✅ PASS — line 71 references `/config/` (trailing slash present) | +| Caddy admin API trailing slash (script) | All 6 occurrences of `localhost:2119/config` in script | ✅ PASS — all use `/config/` | + +--- + +## Security Focus Area Results + +### 1. Credential Handling — `TMP_COOKIE` + +**`mktemp` usage**: `TMP_COOKIE=$(mktemp)` at line 208. Creates a file in `/tmp` with `600` permissions via the OS. ✅ SECURE. + +**Removal on exit**: The `cleanup()` function at line 103 removes the file with `rm -f "${TMP_COOKIE:-}"`. However, `cleanup` is only registered via explicit calls — there is **no `trap cleanup EXIT`**. Only `trap on_failure ERR` is registered (line 108). + +**Gap**: On 5 early `exit 1` paths after line 208 (login failure L220, auth failure L251, Caddy readiness failure L282, security config failure L299, and handler verification failure L316), `cleanup` is never called. The cookie file is left in `/tmp`. + +**Severity**: LOW — The cookie contains session credentials for a localhost test server (`ratelimit@example.local` / `password123`, non-production). CI runners are ephemeral and auto-cleaned. Local runs will leave a `/tmp/tmp.XXXXXX` file until next reboot or manual cleanup. + +**Note**: The exit at line 386 (inside the 429 enforcement failure block) intentionally skips cleanup to leave containers running for manual inspection. This is by design and acceptable. + +**Recommendation**: Add `trap cleanup EXIT` immediately after `trap on_failure ERR` (line 109) to ensure the cookie file is always removed. + +--- + +### 2. `curl` — Sensitive Values in Command-Line Arguments + +Cookie file path is passed via `-c ${TMP_COOKIE}` and `-b ${TMP_COOKIE}` (unquoted). No credentials, tokens, or API keys are passed as command-line arguments. All authentication is via the cookie file (read/write by path), which is the correct pattern — cookie values never appear in `ps` output. + +**Finding (LOW)**: `${TMP_COOKIE}` is unquoted in all 6 curl invocations. `mktemp` on Linux produces paths of the form `/tmp/tmp.XXXXXX` which never contain spaces or shell metacharacters under default `$TMPDIR`. However, under a non-standard `$TMPDIR` (e.g., `/tmp/my dir/`) this would break. This is a portability issue, not a security issue. + +**Recommendation**: Quote `"${TMP_COOKIE}"` in all curl invocations. + +--- + +### 3. Shell Injection + +All interpolated values in curl `-d` payloads are either: +- Script-level constants (`RATE_LIMIT_REQUESTS=3`, `RATE_LIMIT_WINDOW_SEC=10`, `RATE_LIMIT_BURST=1`, `TEST_DOMAIN=ratelimit.local`, `BACKEND_CONTAINER=ratelimit-backend`) +- Values derived from API responses stored in double-quoted variables (`"$CREATE_RESP"`, `"$SEC_CONFIG_RESP"`) + +No shell injection vector exists. All heredoc expansions (`cat < sbom-generated.json`. + +### Delete or Gitignore `.trivy_logs/charon_binary` + +The 23MB stale binary `.trivy_logs/charon_binary` (go1.25.4, Nov 2025) is a Trivy scan artifact causing several Critical/High CVE findings. Add `.trivy_logs/*.binary` or the whole `.trivy_logs/` directory to `.gitignore`. + +--- + +## 5. Summary + +| # | Finding | Severity | False Positive? | Action Required | +|---|---|---|---|---| +| 1 | CVE-2025-68121 in `.trivy_logs/charon_binary` + `backend/bin/*` | **Critical** | No | Rebuild binaries with go1.26.1; delete stale `.trivy_logs/charon_binary` | +| 2 | CVE-2026-33186 in Charon source | — | N/A | **Already fixed** (v1.79.3) | +| 3 | CVE-2026-33186 in CrowdSec/Caddy binaries | High | Yes (for Charon) | Upgrade CrowdSec and Caddy Docker image tags | +| 4 | GHSA-479m-364c-43vc (`goxmldsig`) | Medium | **Yes** | Upgrade Caddy Docker image | +| 5 | GHSA-6g7g-w4f8-9c9x (`jsonparser`) | Medium | **Yes** | Upgrade CrowdSec Docker image | +| 6 | GHSA-jqcq-xjh3-6g23 (`pgproto3/v2`) | Medium | **Yes** | Upgrade CrowdSec Docker image | +| 7 | High stdlib CVEs in `backend/bin/` binaries | High | No | Rebuild with go1.26.1 | +| 8 | Python venv packages | Medium | No (dev only) | `pip upgrade` in local envs | +| 9 | Module cache false positives | Critical–High | **Yes** | Exclude `.cache/` from `grype dir:.` | +| 10 | Stale `sbom-generated.json` | — | Yes | Delete or regenerate | +