fix(security): update known vulnerabilities section in SECURITY.md to reflect critical CVE-2025-68121 and additional high-severity issues

This commit is contained in:
GitHub Actions
2026-03-21 00:10:32 +00:00
parent 586f7cfc98
commit 4284bcf0b6
6 changed files with 1169 additions and 2627 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,153 @@
# QA Final Validation Report — Security Remediation 2026-03-20
**Date:** 2026-03-20
**Auditor:** QA Security Auditor (automated)
**Scope:** Code changes and SECURITY.md updates from today's security remediation session
---
## Summary
| Check | Result |
|-------|--------|
| Code changes verified | PASS |
| SECURITY.md structure verified | PASS |
| Build (`go build`, `go vet`) | PASS |
| Pre-commit hooks | N/A — config missing (see note) |
| Go tests (mail + docker services) | PASS |
| **Overall** | **PASS** |
---
## Step 1: Code Change Verification
### 1.1 `Dockerfile` — Go version bump
| Item | Expected | Actual | Result |
|------|----------|--------|--------|
| Line 13 | `ARG GO_VERSION=1.26.2` | `ARG GO_VERSION=1.26.2` | ✅ PASS |
### 1.2 `backend/internal/services/mail_service.go` — gosec suppression
| Item | Expected | Actual | Result |
|------|----------|--------|--------|
| `#nosec G203` comment present | Yes | `// #nosec G203 -- html/template.Execute auto-escapes all EmailTemplateData fields; this cast prevents double-escaping in the outer layout.` | ✅ PASS |
| `//nolint:gosec` annotation present | Yes | `//nolint:gosec // see above` | ✅ PASS |
| Comment mentions auto-escaping justification | Yes | Present — cites `html/template.Execute` auto-escaping and double-escaping prevention | ✅ PASS |
### 1.3 `backend/internal/services/docker_service_test.go` — file permission
| Item | Expected | Actual | Result |
|------|----------|--------|--------|
| `os.WriteFile` permission (~line 231) | `0o600` | `0o600` | ✅ PASS |
---
## Step 2: SECURITY.md Structure Verification
| Check | Expected | Result |
|-------|----------|--------|
| Section order | Preamble → Known Vulnerabilities → Patched Vulnerabilities → supporting sections | ✅ PASS |
| CVE-2025-68121 ID field | `CVE-2025-68121 (see also CHARON-2025-001)` | ✅ PASS |
| CVE-2025-68121 Severity | Critical | ✅ PASS |
| CVE-2026-2673 present in Known Vulnerabilities | Yes | ✅ PASS |
| CVE-2026-2673 Severity | High | ✅ PASS (`High · 7.5`) |
| CVE-2026-2673 Status | Awaiting Upstream | ✅ PASS |
| CHARON-2025-001 mentions Go 1.25.1 as cluster origin | Yes | ✅ PASS |
| CHARON-2025-001 mentions Go 1.25.6/1.25.7 partial fixes | Yes | ✅ PASS |
| CHARON-2025-001 identifies CVE-2025-68121 as Critical | Yes | ✅ PASS |
| CHARON-2025-001 states resolution requires Go ≥ 1.26.2 | Yes | ✅ PASS |
| CHARON-2026-001 present in Patched (not Known) | Yes | ✅ PASS |
| CHARON-2026-001 Resolution links `docs/plans/alpine_migration_spec.md` | Yes | ✅ PASS |
| CHARON-2026-001 Resolution links `docs/security/advisory_2026-02-04_debian_cves_temporary.md` | Yes | ✅ PASS |
| CVE-2025-68156 present in Patched | Yes | ✅ PASS |
---
## Step 3: Build Verification
**Command:** `cd /projects/Charon/backend && go build ./... && go vet ./...`
| Result | Details |
|--------|---------|
| Exit code | 0 |
| Build errors | None |
| Vet warnings | None |
| **PASS** | Clean build and vet with zero diagnostics |
---
## Step 4: Pre-commit Hooks
**Command:** `cd /projects/Charon && pre-commit run --all-files`
| Result | Details |
|--------|---------|
| Exit code | Non-zero (fatal) |
| Error | `InvalidConfigError: .pre-commit-config.yaml is not a file` |
| Hooks executed | 0 |
| **STATUS: N/A** | `.pre-commit-config.yaml` does not exist in the workspace. No regressions can be inferred; pre-commit infrastructure is absent, not broken by today's changes. |
> **Note:** The absence of `.pre-commit-config.yaml` is a pre-existing infrastructure gap, not a regression introduced by today's session. No hooks (go-vet, golangci-lint, eslint, prettier, gitleaks, etc.) could be evaluated via this pathway. The Go build/vet and test steps below serve as a substitute for the Go-related hooks.
---
## Step 5: Go Tests for Modified Files
### 5.1 Mail Service Tests
**Command:** `cd /projects/Charon/backend && go test ./internal/services/... -run "TestMail" -v`
| Test | Result |
|------|--------|
| TestMailService_SendEmail_CRLFInjection_Comprehensive | PASS |
| TestMailService_BuildEmail_UndisclosedRecipients | PASS |
| TestMailService_SendInvite_HTMLTemplateEscaping | PASS |
| TestMailService_SendInvite_CRLFInjection | PASS |
| TestMailService_GetSMTPConfig_DBError | PASS |
| TestMailService_GetSMTPConfig_InvalidPortFallback | PASS |
| TestMailService_BuildEmail_NilAddressValidation | PASS |
| TestMailService_sendSSL_DialFailure | PASS |
| TestMailService_sendSTARTTLS_DialFailure | PASS |
| TestMailService_TestConnection_StartTLSSuccessWithAuth | PASS |
| TestMailService_TestConnection_NoneSuccess | PASS |
| TestMailService_SendEmail_STARTTLSSuccess | PASS |
| TestMailService_SendEmail_SSLSuccess | PASS |
| TestMailService_SendEmail_ContextCancelled | PASS |
| **Package result** | `ok` in 0.594s |
Two benign teardown warnings appeared (`failed to close smtp client/tls conn: use of closed network connection`) — expected test-cleanup noise, did not cause failures.
### 5.2 Docker Service Tests
**Command:** `cd /projects/Charon/backend && go test ./internal/services/... -run "TestBuildLocalDocker" -v`
| Test | Result |
|------|--------|
| TestBuildLocalDockerUnavailableDetails_PermissionDeniedIncludesGroupHint | PASS |
| TestBuildLocalDockerUnavailableDetails_MissingSocket | PASS |
| TestBuildLocalDockerUnavailableDetails_PermissionDeniedSocketGIDInGroups | PASS |
| TestBuildLocalDockerUnavailableDetails_PermissionDeniedStatFails | PASS |
| TestBuildLocalDockerUnavailableDetails_ConnectionRefused | PASS |
| TestBuildLocalDockerUnavailableDetails_GenericError | PASS |
| TestBuildLocalDockerUnavailableDetails_OsErrNotExist | PASS |
| TestBuildLocalDockerUnavailableDetails_NonUnixHost | PASS |
| TestBuildLocalDockerUnavailableDetails_EPERMWithStatFail | PASS |
| **Package result** | `ok` in 0.168s |
---
## Issues / Blocking Findings
None. All verifiable checks passed.
### Non-blocking Notes
1. **Pre-commit config absent**`.pre-commit-config.yaml` does not exist; pre-commit hooks cannot run. This is a pre-existing gap, not introduced by today's session. Recommend creating a pre-commit config to enable linting gates.
2. **`TestDocker` pattern produced no matches** — the actual docker service test functions follow the naming pattern `TestBuildLocalDockerUnavailableDetails_*`. The pattern in the original mission brief was too narrow; tests were re-run with the correct pattern and all passed.
---
## Overall
**PASS** — All code changes are correctly applied, SECURITY.md structure meets all specified criteria, the backend builds and vets cleanly, and all relevant unit tests pass with zero failures.

View File

@@ -1,158 +1,289 @@
# QA Security Scan Report
**Date**: 2026-03-18
**Scope**: Charon project — filesystem + Docker image
**Scanners**: Trivy (filesystem), Grype (Docker image via `security-scan-docker-image` skill)
**Previous scan data reviewed**: `trivy-report.json`, `trivy-image-report.json`, `grype-results.json`, `vuln-results.json`
**Date**: 2026-03-20
**Scope**: Charon project — full stack (filesystem, Go modules, npm, Docker image, source code)
**Scanners**: grype (live + cached), Trivy (cached), govulncheck (live), npm audit (live), golangci-lint/gosec (live)
**Scan results reviewed**: `trivy-report.json`, `trivy-image-report.json`, `grype-results.json`, `vuln-results.json`
**Project Go version**: go 1.26.1 (Charon backend), go 1.25.61.25.7 (CrowdSec bundled binaries)
**Container OS**: Alpine Linux 3.23.3
---
## Executive Summary
The CI supply chain run flagged **2 HIGH severity vulnerabilities**. Both are the same CVE affecting two sibling OpenSSL packages in the Alpine 3.23.3 base image. **Neither has a fixed Alpine package version available as of the scan date.** This is an upstream-blocked situation requiring monitoring, not an immediately actionable code change.
| Severity | Total Found | Patchable Now | Awaiting Upstream | Code Fix Required | Already Resolved |
|----------|-------------|---------------|-------------------|-------------------|------------------|
| CRITICAL | 1 | 1 | 0 | 0 | — |
| HIGH | 7 | 2 | 3 | 1 | 3 |
| MEDIUM | 6 | 4 | 1 | 1 | — |
| LOW | 4 | 3 | 1 | 1 | — |
| **Total** | **18** | **10** | **4** | **3** | **3** |
No CRITICAL findings exist in any scan component (filesystem, Go modules, npm, or Docker image).
**Key narrative:**
- The Alpine base image migration (CHARON-2026-001) is **complete**. `charon:local` confirmed Alpine 3.23.3. The 7 Debian HIGH CVEs are gone.
- A **new CRITICAL CVE** (CVE-2025-68121) was discovered in CrowdSec's bundled Go binaries compiled with go1.25.6. This is the most urgent finding.
- Two **new HIGH CVEs** in those same bundled binaries (CVE-2026-25679, CVE-2025-61732) are also actionable — all three resolve by rebuilding CrowdSec against go ≥ 1.25.8.
- **CVE-2026-2673** (OpenSSL TLS 1.3 key exchange group downgrade) affects `libcrypto3` and `libssl3` in Alpine 3.23.3. No Alpine package fix exists yet (advisory: 2026-03-13).
- Charon's own Go backend (go 1.26.1) and all npm dependencies are **clean with zero vulnerabilities**.
- CVE-2026-25793 (nebula in Caddy) is **resolved** by the CADDY_PATCH_SCENARIO=B Dockerfile change.
---
## Findings
## Findings Table
### Finding 1 — CVE-2026-2673 [HIGH] in `libcrypto3`
### CRITICAL
| # | CVE ID | CVSS | Package | Installed | Fixed In | Component | Status | New? |
|---|--------|------|---------|-----------|----------|-----------|--------|------|
| C-1 | CVE-2025-68121 | Critical | `stdlib` (Go) | go1.25.6 | go1.25.7 | CrowdSec bundled binaries | PATCHABLE | ✅ NEW |
### HIGH
| # | CVE / ID | CVSS | Package | Installed | Fixed In | Component | Status | New? |
|---|----------|------|---------|-----------|----------|-----------|--------|------|
| H-1 | CVE-2026-2673 | 7.5 | `libcrypto3` | 3.5.5-r0 | None | Alpine 3.23.3 base image | AWAITING UPSTREAM | ✅ NEW |
| H-2 | CVE-2026-2673 | 7.5 | `libssl3` | 3.5.5-r0 | None | Alpine 3.23.3 base image | AWAITING UPSTREAM | ✅ NEW |
| H-3 | CVE-2026-25679 | High | `stdlib` (Go) | go1.25.6 & go1.25.7 | go1.25.8 | CrowdSec bundled binaries | PATCHABLE | ✅ NEW |
| H-4 | CVE-2025-61732 | High | `stdlib` (Go) | go1.25.6 | go1.25.7 | CrowdSec bundled binaries | PATCHABLE | ✅ NEW |
| H-5 | CHARON-2025-001 | High | CrowdSec binaries (Go stdlib) | go < 1.26 | Upstream rebuild | CrowdSec Agent (CVE-2025-58183/58186/58187/61729) | AWAITING UPSTREAM | Known |
| H-6 | DS-0002 | High (misconfig) | `Dockerfile` | — | Add `USER` instruction | Container configuration | CODE FIX | ✅ NEW |
> **Note on H-3 / H-4 and CHARON-2025-001**: The original CHARON-2025-001 CVEs tracked CrowdSec binaries at go1.25.1. Current scans show binaries at go1.25.6/go1.25.7, indicating CrowdSec was updated but remains behind go1.25.8. The new CVEs (C-1, H-3, H-4) are continuations of the same class of issue.
### MEDIUM
| # | CVE / ID | CVSS | Package | Installed | Fixed In | Component | Status | New? |
|---|----------|------|---------|-----------|----------|-----------|--------|------|
| M-1 | CVE-2025-60876 | 6.5 | `busybox`, `busybox-binsh`, `busybox-extras`, `ssl_client` | 1.37.0-r30 | None (per grype scan) | Alpine 3.23.3 base image | AWAITING UPSTREAM | ✅ NEW¹ |
| M-2 | CVE-2026-27142 | Medium | `stdlib` (Go) | go1.25.6 & go1.25.7 | go1.25.8 | CrowdSec bundled binaries | PATCHABLE | ✅ NEW |
| M-3 | GHSA-qmgc-5h2g-mvrw | Medium | `filelock` | 3.20.0 | 3.20.3 | Python dev tooling | PATCHABLE | ✅ NEW |
| M-4 | GHSA-w853-jp5j-5j7f | Medium | `filelock` | 3.20.0 | 3.20.1 | Python dev tooling | PATCHABLE | ✅ NEW |
| M-5 | GHSA-597g-3phw-6986 | Medium | `virtualenv` | 20.35.4 | 20.36.1 | Python dev tooling | PATCHABLE | ✅ NEW |
| M-6 | G203 (gosec) | Medium | `mail_service.go:195` | `template.HTML()` | Sanitize input | Charon backend (Go) | CODE FIX | ✅ NEW |
> ¹ SECURITY.md stated Alpine patched CVE-2025-60876; `grype-results.json` image scan shows no fix for busybox 1.37.0-r30. Verify with a fresh container build before treating as actively exploitable.
### LOW
| # | CVE / ID | CVSS | Package | Installed | Fixed In | Component | Status | New? |
|---|----------|------|---------|-----------|----------|-----------|--------|------|
| L-1 | GHSA-fw7p-63qq-7hpr | 1.7 | `filippo.io/edwards25519` | v1.1.0 | v1.1.1 | CrowdSec bundled binaries | PATCHABLE | ✅ NEW |
| L-2 | CVE-2026-27139 | Low | `stdlib` (Go) | go1.25.6 & go1.25.7 | go1.25.8 | CrowdSec bundled binaries | PATCHABLE | ✅ NEW |
| L-3 | GHSA-6vgw-5pg2-w6jp | Low | `pip` | 25.3 | 26.0 | Python dev tooling | PATCHABLE | ✅ NEW |
| L-4 | G306 (gosec) | Low (misconfig) | `docker_service_test.go:231` | `0o660` | Change to `0o600` | Charon test code | CODE FIX | ✅ NEW |
---
## Patchable CVEs (Fix Available Now)
### P-1 · CVE-2025-68121 [CRITICAL] — Go stdlib in CrowdSec binaries
| Field | Value |
|-------|-------|
| CVE | CVE-2026-2673 |
| Severity | HIGH (CVSS 7.5) |
| Package | `libcrypto3` |
| Installed Version | `3.5.5-r0` |
| Fixed Version | **None available** |
| Fix State | Unknown / Upstream-pending |
| Component | Docker image final stage (Alpine 3.23.3 APK) |
| Scanner | Grype `security-scan-docker-image` |
| Advisory Published | 2026-03-13 |
| CVSS | Critical |
| Package | `stdlib` (Go) |
| Affected | go1.25.6 and earlier |
| Fixed in | go1.25.7 |
| Component | CrowdSec bundled binaries (`cscli`, `crowdsec`) |
| Fix action | Rebuild CrowdSec against go ≥ 1.25.8 (also resolves H-3, H-4, M-2, L-1, L-2) |
**Description**: An OpenSSL TLS 1.3 server may fail to negotiate the expected preferred key exchange group when its key exchange group configuration includes the `DEFAULT` keyword. This can result in weaker cipher negotiation than intended, potentially enabling downgrade attacks on TLS connections.
**References**:
- https://openssl-library.org/news/secadv/20260313.txt
- https://github.com/openssl/openssl/commit/2157c9d81f7b0bd7dfa25b960e928ec28e8dd63f
- https://github.com/openssl/openssl/commit/85977e013f32ceb96aa034c0e741adddc1a05e34
- http://www.openwall.com/lists/oss-security/2026/03/13/3
govulncheck reports Charon's own backend (go 1.26.1) as clean. The vulnerability is exclusively in the CrowdSec agent binaries bundled in the container image. This is the **highest priority finding** in this audit.
---
### Finding 2 CVE-2026-2673 [HIGH] in `libssl3`
### P-2 · CVE-2026-25679 [HIGH] + P-3 · CVE-2025-61732 [HIGH] — Go stdlib in CrowdSec binaries
Both reside in CrowdSec bundled binaries compiled with go1.25.6/go1.25.7. CVE-2026-25679 requires go1.25.8; CVE-2025-61732 resolves at go1.25.7.
**Fix action**: same as P-1 — rebuild CrowdSec against go ≥ 1.25.8.
---
### P-4 through P-8 — Python dev tooling (Medium/Low)
These affect only the development environment, not the production container:
| ID | Package | Fix |
|----|---------|-----|
| GHSA-qmgc-5h2g-mvrw | `filelock` 3.20.0 | `pip install --upgrade filelock` (→ 3.20.3) |
| GHSA-w853-jp5j-5j7f | `filelock` 3.20.0 | same |
| GHSA-597g-3phw-6986 | `virtualenv` 20.35.4 | `pip install --upgrade virtualenv` (→ 20.36.1) |
| GHSA-6vgw-5pg2-w6jp | `pip` 25.3 | `pip install --upgrade pip` (→ 26.0) |
---
## Awaiting Upstream
### U-1 · CVE-2026-2673 [HIGH] × 2 — OpenSSL TLS 1.3 key group downgrade
| Field | Value |
|-------|-------|
| CVE | CVE-2026-2673 |
| Severity | HIGH (CVSS 7.5) |
| Package | `libssl3` |
| Installed Version | `3.5.5-r0` |
| Fixed Version | **None available** |
| Fix State | Unknown / Upstream-pending |
| Component | Docker image final stage (Alpine 3.23.3 APK) |
| Scanner | Grype `security-scan-docker-image` |
| Advisory Published | 2026-03-13 |
| CVSS | 7.5 |
| Packages | `libcrypto3` and `libssl3` |
| Installed | 3.5.5-r0 (Alpine 3.23.3) |
| Fixed in | No Alpine APK available as of 2026-03-20 |
| Advisory | 2026-03-13 — https://openssl-library.org/news/secadv/20260313.txt |
| Component | Docker base image (Alpine 3.23.3) |
**Description**: Same CVE as Finding 1. `libssl3` and `libcrypto3` are sibling packages that constitute Alpine's OpenSSL 3.5.5 installation. Both packages must be patched together.
An OpenSSL TLS 1.3 server may fail to negotiate the intended key exchange group when the configuration includes the `DEFAULT` keyword, potentially allowing downgrade to weaker cipher suites. Charon's Caddy configuration does not use `DEFAULT` key groups explicitly, limiting practical impact.
**Monitor**: https://security.alpinelinux.org/vuln/CVE-2026-2673
When Alpine releases the patch, update the pinned `ALPINE_IMAGE` digest in the Dockerfile or extend the runtime stage:
```dockerfile
RUN apk upgrade --no-cache zlib libcrypto3 libssl3
```
---
## Classification
### U-2 · CHARON-2025-001 [HIGH] — CrowdSec Go stdlib CVEs (original cluster)
| CVE | Package | Classification | Reason |
|-----|---------|----------------|--------|
| CVE-2026-2673 | libcrypto3@3.5.5-r0 | **Waiting on Upstream** | No fixed Alpine APK available; advisory published 5 days ago |
| CVE-2026-2673 | libssl3@3.5.5-r0 | **Waiting on Upstream** | Same CVE, same upstream blocking condition |
Tracked in SECURITY.md: CVE-2025-58183, CVE-2025-58186, CVE-2025-58187, CVE-2025-61729. CrowdSec was updated from go1.25.1 to go1.25.6/go1.25.7 (the original CVEs may have been resolved) but go stdlib CVEs continue to accumulate. All resolve when CrowdSec releases a build using go ≥ 1.25.8.
---
## Historical Finding (Resolved)
### CVE-2026-25793 [HIGH] in `github.com/slackhq/nebula` — **RESOLVED**
### U-3 · CVE-2025-60876 [MEDIUM] — busybox 1.37.0-r30 (Alpine)
| Field | Value |
|-------|-------|
| CVE | CVE-2026-25793 |
| Severity | HIGH |
| Package | `github.com/slackhq/nebula` |
| Vulnerable Version | v1.9.7 |
| Fixed Version | v1.10.3 |
| Component | `usr/bin/caddy` (Go binary) |
| Status | **Resolved** |
| CVSS | 6.5 |
| Packages | `busybox`, `busybox-binsh`, `busybox-extras`, `ssl_client` |
| Installed | 1.37.0-r30 |
| Fixed in | Not available per `grype-results.json` scan |
| Component | Alpine 3.23.3 base image |
This finding appeared in the `trivy-image-report.json` scan from 2026-02-25, when the Dockerfile used `CADDY_PATCH_SCENARIO=A`, which explicitly pinned nebula to v1.9.7. The Dockerfile was updated to `CADDY_PATCH_SCENARIO=B` (see `Dockerfile:42`), which skips the explicit nebula pin and allows upstream resolution. The finding does not appear in the current (2026-03-18) Docker image scan.
SECURITY.md previously stated Alpine patched CVE-2025-60876. The `grype-results.json` image scan still shows no fix version. Verify with a fresh `grype` container scan before acting.
---
## False Positives / Already Mitigated
### R-1 · CHARON-2026-001 — Debian Base Image CVE cluster — RESOLVED
The 7 HIGH Debian Trixie CVEs (`libc6`, `libc-bin`, `libtasn1-6`, `libtiff`) are fully gone. The `charon:local` image confirmed Alpine Linux 3.23.3. No action required.
---
### R-2 · CVE-2026-25793 — nebula v1.9.7 in `usr/bin/caddy` — RESOLVED
The `CADDY_PATCH_SCENARIO=B` Dockerfile change removed the explicit nebula v1.9.7 pin. The finding does not appear in the 2026-03-18 Docker image scan. No action required.
---
### R-3 · CVE-2025-68156 — `expr-lang/expr` ReDoS — PATCHED
Resolved 2026-01-11 by upgrading CrowdSec to a build using `expr-lang/expr` v1.17.7. No finding in any current scan.
---
### R-4 · G203 (gosec) — `mail_service.go:195` template.HTML()
`template.HTML(contentBuf.String())` bypasses Go's auto-escaping. Only exploitable if `contentBuf` contains attacker-controlled HTML. If content is generated entirely from internal trusted templates, this is a false positive. Audit the call site; if any user input flows in, sanitize before casting. If fully internal, suppress via `//nolint:gosec` with a justification comment.
---
### R-5 · G306 (gosec) — `docker_service_test.go:231` file permissions 0o660
Test-only, no production risk. The fix is trivial: change `0o660` to `0o600`.
---
## Recommended Actions (Prioritized)
### Priority 1 — URGENT: Rebuild CrowdSec with Go ≥ 1.25.8
**Resolves**: CVE-2025-68121 (Critical), CVE-2026-25679 (High), CVE-2025-61732 (High), CVE-2026-27142 (Medium), CVE-2026-27139 (Low), GHSA-fw7p-63qq-7hpr (Low), supersedes CHARON-2025-001 original CVEs.
Update the CrowdSec build stage Go toolchain pin in the Dockerfile:
```dockerfile
ARG GOLANG_IMAGE=golang:1.25.8-alpine3.23
```
---
### Priority 2 — Monitor Alpine for CVE-2026-2673 patch
No code change is actionable today. Monitor https://security.alpinelinux.org/vuln/CVE-2026-2673. Once available, update `ALPINE_IMAGE` digest or add `libcrypto3 libssl3` to the `apk upgrade` line.
---
### Priority 3 — Fix Dockerfile root user (DS-0002)
Add a non-root `USER` instruction to the Dockerfile final stage. Verify runtime paths are owned by the new user before deploying.
```dockerfile
RUN addgroup -S charon && adduser -S charon -G charon
USER charon
```
---
### Priority 4 — Audit mail_service.go template.HTML cast
Audit data flow into `internal/services/mail_service.go:195`. Suppress with `//nolint:gosec` if fully internal, or sanitize user input before casting.
---
### Priority 5 — Fix test file permissions
Change `0o660``0o600` at `internal/services/docker_service_test.go:231`.
---
### Priority 6 — Update Python dev tooling
```bash
pip install --upgrade filelock virtualenv pip
```
---
### Priority 7 — Verify CVE-2025-60876 busybox status
Run a fresh `grype` scan against the current `charon:local` image and confirm whether busybox is patched. Update tracking accordingly.
---
## Scan Coverage Summary
| Scan Target | Scanner | HIGH | CRITICAL | Notes |
|-------------|---------|------|----------|-------|
| Filesystem (Go modules, npm, config) | Trivy | 0 | 0 | Clean |
| Docker image (APK packages) | Grype | 2 | 0 | CV-2026-2673 ×2 |
| Docker image (Go binaries) | Grype | 0 | 0 | Nebula CVE resolved |
| Go backend (grype-results.json) | Grype | 0 | 0 | Clean |
| Scan | Target | Tool | CRITICAL | HIGH | MEDIUM | LOW | Notes |
|------|--------|------|----------|------|--------|-----|-------|
| Filesystem (live, 2026-03-20) | `/projects/Charon` | grype | 1 | 2 | 3 | 3 | Go stdlib in CrowdSec binaries; Python tooling |
| Image (cached 2026-02-25) | `charon:local` (Alpine 3.23.3) | Trivy | 0 | 1 | 0 | 0 | CVE-2026-25793 nebula (RESOLVED) |
| Image (skill runner, 2026-03-18) | `charon:local` (Alpine 3.23.3) | grype | 0 | 2 | 4 | 1 | CVE-2026-2673 OpenSSL; busybox; edwards25519 |
| Repository (cached 2026-02-20) | `/app` | Trivy | 0 | 1 (miscfg) | 0 | 0 | DS-0002 Dockerfile root |
| Repository (cached 2026-02-25) | `/app` | Trivy | 0 | 0 | 0 | 0 | Clean across go.mod + npm |
| Go modules (live, 2026-03-20) | `backend/...` | govulncheck | 0 | 0 | 0 | 0 | ✅ Clean |
| npm (live, 2026-03-20) | `/projects/Charon` | npm audit | 0 | 0 | 0 | 0 | ✅ Clean (281 deps) |
| Source code (live, 2026-03-20) | `backend/internal/...` | golangci-lint/gosec | 0 | 0 | 1 | 1 | G203 XSS; G306 permissions |
---
## Root Cause Analysis
## CVE Status vs SECURITY.md
The two HIGH findings share a single root cause: Alpine Linux has not yet published a patched `openssl` package for CVE-2026-2673. The advisory was disclosed on 2026-03-13 (5 days before this scan). The upstream OpenSSL commits exist, but Alpine's package maintainers have not yet issued an `openssl-3.5.x-r1` or newer release.
The Charon Dockerfile pins to `alpine:3.23.3@sha256:2510...` (see `Dockerfile:16`). The final runtime stage installs OpenSSL indirectly as a dependency of `ca-certificates` and other system libs. The existing `apk upgrade --no-cache zlib` on the final stage line 422 targets only zlib and would not pick up an OpenSSL fix even if one were available.
---
## Recommended Actions
### Immediate (No action possible yet)
No code change can resolve CVE-2026-2673 today. Both packages lack a fixed version in Alpine's package repository.
**Monitor**:
- Alpine Linux security tracker: https://security.alpinelinux.org/vuln/CVE-2026-2673
- Alpine 3.23 changelogs for an `openssl-3.5.5-r1` or later release
### When Alpine Releases a Patch
One of the following approaches will resolve both findings simultaneously:
**Option A — Update the pinned base image** (preferred for reproducibility):
```dockerfile
# In Dockerfile, update ARG ALPINE_IMAGE to the new digest when Alpine patches it
ARG ALPINE_IMAGE=alpine:3.23.4@sha256:<new-digest>
```
Renovate will detect and propose this update automatically once Alpine tags a new release.
**Option B — Add explicit runtime upgrade in the final stage**:
```dockerfile
# In Dockerfile final stage, extend the existing apk upgrade line:
RUN apk add --no-cache \
bash ca-certificates sqlite-libs sqlite tzdata gettext libcap libcap-utils \
c-ares busybox-extras \
&& apk upgrade --no-cache zlib libcrypto3 libssl3
```
This would pull the patched version on each image build without waiting for a new Alpine base image tag. The tradeoff is slightly reduced reproducibility.
---
## go.mod / package.json Assessment
- `backend/go.mod`: No occurrences of `openssl`, `nebula`, or `libssl`. Backend Go module tree is clean.
- `package.json` (root): Three production dependencies (`@typescript/analyze-trace`, `tldts`, `type-check`) — none flagged by any scanner.
- `frontend/package.json`: Not independently surfacing any HIGH/CRITICAL findings in the Trivy filesystem scan.
---
## Verdict
| Category | Status |
|----------|--------|
| CRITICAL vulnerabilities | ✅ None found |
| HIGH vulnerabilities — actionable now | ✅ None (0 fixable items) |
| HIGH vulnerabilities — upstream-blocked | ⚠️ 2 (CVE-2026-2673 in libcrypto3 + libssl3) |
| Historical HIGH (nebula) | ✅ Resolved via CADDY_PATCH_SCENARIO=B |
| CVE / ID | In SECURITY.md | Current Status |
|----------|----------------|----------------|
| CHARON-2026-001 (Debian CVE cluster) | Yes | ✅ RESOLVED — Alpine migration complete |
| CHARON-2025-001 (CVE-2025-58183/58186/58187/61729) | Yes | ⚠️ ONGOING — CVE cluster updated; now also includes CVE-2025-68121 (Critical), CVE-2026-25679 (High), CVE-2025-61732 (High) |
| CVE-2025-68156 (expr-lang/expr) | Yes | ✅ PATCHED |
| CVE-2025-68121 | **No — NEW** | 🔴 OPEN — Critical, CrowdSec go1.25.6 |
| CVE-2026-2673 (×2) | **No — NEW** | 🟠 OPEN — High, Alpine OpenSSL, awaiting upstream |
| CVE-2026-25679 | **No — NEW** | 🟠 OPEN — High, CrowdSec go1.25.6/1.25.7 |
| CVE-2025-61732 | **No — NEW** | 🟠 OPEN — High, CrowdSec go1.25.6 |
| DS-0002 | **No — NEW** | 🟠 OPEN — High misconfiguration, Dockerfile root |
| CVE-2025-60876 | **No — NEW** | 🟡 OPEN — Medium, busybox; verify Alpine patch status |
| CVE-2026-27142 | **No — NEW** | 🟡 OPEN — Medium, CrowdSec go1.25.6/1.25.7 |
| GHSA-qmgc-5h2g-mvrw | **No — NEW** | 🟡 OPEN — Medium, filelock (dev tooling) |
| GHSA-w853-jp5j-5j7f | **No — NEW** | 🟡 OPEN — Medium, filelock (dev tooling) |
| GHSA-597g-3phw-6986 | **No — NEW** | 🟡 OPEN — Medium, virtualenv (dev tooling) |
| G203 (gosec) | **No — NEW** | 🟡 OPEN — Medium, mail_service.go XSS risk |
| GHSA-fw7p-63qq-7hpr | **No — NEW** | 🟢 OPEN — Low, edwards25519 v1.1.0 (CrowdSec) |
| CVE-2026-27139 | **No — NEW** | 🟢 OPEN — Low, CrowdSec go1.25.6/1.25.7 |
| GHSA-6vgw-5pg2-w6jp | **No — NEW** | 🟢 OPEN — Low, pip 25.3 (dev tooling) |
| G306 (gosec) | **No — NEW** | 🟢 OPEN — Low, test file permissions |
| CVE-2026-25793 (nebula) | No | ✅ RESOLVED — CADDY_PATCH_SCENARIO=B applied |
**No immediate code changes are required.** Resume monitoring Alpine's security tracker for CVE-2026-2673 patch availability. Once Alpine releases the fix, update `ALPINE_IMAGE` in the Dockerfile or add the explicit `apk upgrade` line for `libcrypto3` and `libssl3`.