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

View File

@@ -27,49 +27,85 @@ public disclosure.
## Known Vulnerabilities
### [HIGH] CHARON-2026-001 · Debian Base Image CVE Cluster
### [CRITICAL] CVE-2025-68121 · Go Stdlib Critical in CrowdSec Bundled Binaries
| Field | Value |
|--------------|-------|
| **ID** | CHARON-2026-001 (aliases: CVE-2026-0861, CVE-2025-15281, CVE-2026-0915, CVE-2025-13151, and 2 libtiff HIGH CVEs) |
| **Severity** | High · 8.4 (highest per CVSS v3.1, preliminary) |
| **Status** | Fix In Progress |
| **ID** | CVE-2025-68121 (see also CHARON-2025-001) |
| **Severity** | Critical |
| **Status** | Awaiting Upstream |
**What**
Seven HIGH-severity CVEs in Debian Trixie base image system libraries (`glibc`, `libtasn1-6`,
`libtiff`). These vulnerabilities reside in the container's OS-level packages. No fixes are
available from the Debian Security Team. The project migrated from Alpine to Debian to avoid
CVE-2025-60876 (busybox heap overflow); now that Alpine has patched that CVE, migration back to
Alpine is underway to eliminate this cluster entirely.
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 (Trivy)
- Reported: 2026-02-04
- Affects: Container runtime environment; no known direct exploitation path through Charon's
application interface
- 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: Debian Trixie base image (`libc6`, `libc-bin`, `libtasn1-6`, `libtiff`)
- Versions affected: All Charon container images built on Debian Trixie base
- 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-02-04
- Disclosed (if public): 2026-02-04 (internal advisory)
- Target fix: 2026-03-05 (Alpine base image migration)
- 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 affected packages are OS-level shared libraries bundled in the container base image.
Exploitation would require local access to the container or a prior application-level compromise
to reach the vulnerable library code. Caddy reverse proxy ingress filtering and container
isolation significantly reduce the effective attack surface.
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**
Revert to Alpine Linux base image (CVE-2025-60876 is now patched upstream). Expected outcome is
100% CVE reduction (7 HIGH → 0).
`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.
- Spec: [docs/plans/alpine_migration_spec.md](docs/plans/alpine_migration_spec.md)
- Advisory: [docs/security/advisory_2026-02-04_debian_cves_temporary.md](docs/security/advisory_2026-02-04_debian_cves_temporary.md)
- Risk Assessment: [docs/security/VULNERABILITY_ACCEPTANCE.md](docs/security/VULNERABILITY_ACCEPTANCE.md)
---
### [HIGH] CVE-2026-2673 · OpenSSL TLS 1.3 Key Exchange Group Downgrade
| Field | Value |
|--------------|-------|
| **ID** | CVE-2026-2673 (affects `libcrypto3` and `libssl3`) |
| **Severity** | High · 7.5 |
| **Status** | Awaiting Upstream |
**What**
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. Affects Alpine 3.23.3 packages `libcrypto3` and `libssl3` at version 3.5.5-r0.
**Who**
- Discovered by: Automated scan (Grype)
- Reported: 2026-03-20
- Affects: Container runtime environment; Caddy reverse proxy TLS negotiation could be affected
if default key group configuration is used
**Where**
- Component: Alpine 3.23.3 base image (`libcrypto3` 3.5.5-r0, `libssl3` 3.5.5-r0)
- Versions affected: Alpine 3.23.3 prior to a patched `openssl` APK release
**When**
- Discovered: 2026-03-20
- Disclosed (if public): 2026-03-13 (OpenSSL advisory)
- Target fix: When Alpine Security publishes a patched `openssl` APK
**How**
When an OpenSSL TLS 1.3 server configuration uses the `DEFAULT` keyword for key exchange groups,
the negotiation logic may select a weaker group than intended. Charon's Caddy TLS configuration
does not use the `DEFAULT` keyword, which limits practical exploitability. The packages are
present in the base image regardless of Caddy's configuration.
**Planned Remediation**
Monitor https://security.alpinelinux.org/vuln/CVE-2026-2673 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 libcrypto3 libssl3` to the runtime stage.
---
@@ -77,30 +113,32 @@ Revert to Alpine Linux base image (CVE-2025-60876 is now patched upstream). Expe
| Field | Value |
|--------------|-------|
| **ID** | CHARON-2025-001 (aliases: CVE-2025-58183, CVE-2025-58186, CVE-2025-58187, CVE-2025-61729) |
| **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 |
**What**
Four HIGH-severity CVEs in Go standard library packages (HTTP/2 handling, TLS certificate
validation, archive parsing) present in CrowdSec binaries bundled with Charon. These vulnerabilities
exist because CrowdSec's distributed binaries were compiled against Go 1.25.1. Charon's own
application code is unaffected.
Multiple CVEs in Go standard library packages continue to accumulate in CrowdSec binaries bundled
with Charon. The cluster originated when CrowdSec was compiled against Go 1.25.1; subsequent
CrowdSec updates advanced the toolchain to Go 1.25.6/1.25.7, resolving earlier CVEs but
introducing new ones. The cluster now includes a Critical-severity finding (CVE-2025-68121,
tracked separately above). All issues resolve when CrowdSec is rebuilt against Go ≥ 1.26.2.
Charon's own application code is unaffected.
**Who**
- Discovered by: Automated scan (Trivy)
- Reported: 2025-12-01
- 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**
- Component: CrowdSec Agent (bundled `cscli` and `crowdsec` binaries)
- Versions affected: All Charon versions shipping CrowdSec binaries compiled against Go < 1.26.0
- Versions affected: All Charon versions shipping CrowdSec binaries compiled against Go < 1.26.2
**When**
- Discovered: 2025-12-01
- Disclosed (if public): Not yet publicly disclosed
- Target fix: Dependent on CrowdSec upstream release timeline
- Target fix: When `golang:1.26.2-alpine` is published on Docker Hub
**How**
The CVEs reside entirely within CrowdSec's compiled binaries and cover HTTP/2, TLS, and archive
@@ -108,13 +146,60 @@ processing paths that are not invoked by Charon's core application logic. The re
interfaces are not externally exposed via Charon's API surface.
**Planned Remediation**
Monitor CrowdSec releases for binaries built with Go 1.26.0+. Upgrade CrowdSec in Charon's build
pipeline as soon as a patched release is available.
`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.
---
## Patched Vulnerabilities
### ✅ [HIGH] CHARON-2026-001 · Debian Base Image CVE Cluster
| Field | Value |
|--------------|-------|
| **ID** | CHARON-2026-001 (aliases: CVE-2026-0861, CVE-2025-15281, CVE-2026-0915, CVE-2025-13151, and 2 libtiff HIGH CVEs) |
| **Severity** | High · 8.4 (highest per CVSS v3.1) |
| **Patched** | 2026-03-20 (Alpine base image migration complete) |
**What**
Seven HIGH-severity CVEs in Debian Trixie base image system libraries (`glibc`, `libtasn1-6`,
`libtiff`). These vulnerabilities resided in the container's OS-level packages with no fixes
available from the Debian Security Team.
**Who**
- Discovered by: Automated scan (Trivy)
- Reported: 2026-02-04
**Where**
- Component: Debian Trixie base image (`libc6`, `libc-bin`, `libtasn1-6`, `libtiff`)
- Versions affected: Charon container images built on Debian Trixie base (prior to Alpine migration)
**When**
- Discovered: 2026-02-04
- Patched: 2026-03-20
- Time to patch: 44 days
**How**
The affected packages were OS-level shared libraries bundled in the Debian Trixie container base
image. Exploitation would have required local container access or a prior application-level
compromise. Caddy reverse proxy ingress filtering and container isolation significantly reduced
the effective attack surface throughout the exposure window.
**Resolution**
Reverted to Alpine Linux base image (Alpine 3.23.3). Alpine's patch of CVE-2025-60876 (busybox
heap overflow) removed the original blocker for the Alpine migration. Post-migration scan
confirmed zero HIGH/CRITICAL CVEs from this cluster.
- Spec: [docs/plans/alpine_migration_spec.md](docs/plans/alpine_migration_spec.md)
- Advisory: [docs/security/advisory_2026-02-04_debian_cves_temporary.md](docs/security/advisory_2026-02-04_debian_cves_temporary.md)
**Credit**
Internal remediation; no external reporter.
---
### ✅ [HIGH] CVE-2025-68156 · expr-lang/expr ReDoS
| Field | Value |

View File

@@ -228,7 +228,7 @@ func TestBuildLocalDockerUnavailableDetails_PermissionDeniedSocketGIDInGroups(t
// Temp file GID = our primary GID (already in process groups) → no group hint
tmpDir := t.TempDir()
socketFile := filepath.Join(tmpDir, "docker.sock")
require.NoError(t, os.WriteFile(socketFile, []byte(""), 0o660))
require.NoError(t, os.WriteFile(socketFile, []byte(""), 0o600))
host := "unix://" + socketFile
err := &net.OpError{Op: "dial", Net: "unix", Err: syscall.EACCES}

View File

@@ -192,7 +192,10 @@ func (s *MailService) RenderNotificationEmail(templateName string, data EmailTem
return "", fmt.Errorf("failed to render template %q: %w", templateName, err)
}
data.Content = template.HTML(contentBuf.String())
// html/template.Execute already escapes all EmailTemplateData fields; the
// template.HTML cast here prevents double-escaping in the outer layout template.
// #nosec G203 -- html/template.Execute auto-escapes all EmailTemplateData fields; this cast prevents double-escaping in the outer layout.
data.Content = template.HTML(contentBuf.String()) //nolint:gosec // see above
baseTmpl, err := template.New("email_base.html").Parse(string(baseBytes))
if err != nil {

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`.