Files
Charon/docs/plans/security_vulnerability_remediation.md
2026-01-26 19:22:05 +00:00

54 KiB

Security Vulnerability Remediation Plan

Date: January 11, 2026 Priority: CRITICAL (2 HIGH, 8 MEDIUM) Estimated Total Time: 6-8 hours (includes CrowdSec source build) Target Completion: Within 48 hours


Executive Summary

This document outlines the remediation plan for security vulnerabilities discovered in recent security scans:

  • 1 HIGH severity vulnerability requiring patching: expr-lang/expr in CrowdSec (CVE-2025-68156)
  • 1 HIGH severity vulnerability already fixed: expr-lang/expr in Caddy (CVE-2025-68156)
  • 1 MEDIUM severity likely false positive: golang.org/x/crypto (requires verification)
  • 8 MEDIUM severity vulnerabilities in Alpine APK packages (busybox, curl, ssl_client)

Most vulnerabilities can be remediated through version upgrades or Alpine package updates without code changes. The CrowdSec expr-lang patch requires Dockerfile modification. Testing and validation are required to ensure no breaking changes affect production functionality.


Vulnerability Inventory

HIGH Severity (CRITICAL - Must fix immediately)

Package Current Version Target Version CVE/Advisory Impact Status
github.com/expr-lang/expr (Caddy) v1.17.2 v1.17.7 CVE-2025-68156, GHSA-cfpf-hrx2-8rv6 Expression evaluator vulnerability (transitive via Caddy plugins) ALREADY FIXED (Dockerfile line 181)
github.com/expr-lang/expr (CrowdSec) v1.17.2 v1.17.7 CVE-2025-68156, GHSA-cfpf-hrx2-8rv6 Expression evaluator vulnerability (used in scenarios/parsers) REQUIRES PATCHING

MEDIUM Severity (High Priority - Fix within 48h)

Note: golang.org/x/crypto advisories are FALSE POSITIVES - v0.46.0 is newer than suggested "target" v0.45.0. Downgraded from HIGH to MEDIUM pending CVE verification.

Package Current Version CVE Impact
busybox 1.37.0-r20 CVE-2025-60876 Alpine APK utility vulnerabilities
busybox-binsh 1.37.0-r20 CVE-2025-60876 Shell interpreter vulnerabilities
curl 8.14.1-r2 CVE-2025-10966 HTTP client vulnerabilities
ssl_client 1.37.0-r20 CVE-2025-60876 SSL/TLS client vulnerabilities

Note: golang.org/x/crypto severity downgraded from HIGH to MEDIUM after research - CVEs may be false positives or already patched in v0.46.0.


Phase 1: Go Module Updates & expr-lang Patching (HIGH PRIORITY)

1.1 golang.org/x/crypto Verification (MEDIUM PRIORITY - Likely False Positive)

Current Usage Analysis

Files importing golang.org/x/crypto:

  • backend/internal/services/security_service.go (bcrypt for password hashing)
  • backend/internal/models/user.go (bcrypt for password storage)

Usage Pattern:

import "golang.org/x/crypto/bcrypt"

// Password hashing
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)

// Password verification
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))

Breaking Changes Assessment

Version Jump: v0.46.0 → v0.45.0

⚠️ CRITICAL ISSUE IDENTIFIED: The target version v0.45.0 is OLDER than current v0.46.0. This is a FALSE POSITIVE from the scanner.

Corrective Action:

  1. Run govulncheck to verify if CVEs actually apply to our usage
  2. Check CVE advisories to confirm v0.46.0 doesn't already contain fixes
  3. If CVEs are real, upgrade to latest stable (not downgrade to v0.45.0)

Expected Outcome: Most likely NO ACTION REQUIRED - v0.46.0 is likely already patched.

Implementation Steps

  1. Verify CVE applicability:

    cd backend
    go run golang.org/x/vuln/cmd/govulncheck@latest ./...
    
  2. Update go.mod (if upgrade needed):

    cd backend
    go get -u golang.org/x/crypto@latest
    go mod tidy
    
  3. Run backend tests:

    cd backend
    go test ./... -v
    
  4. Coverage check:

    cd backend
    go test -coverprofile=coverage.out ./...
    go tool cover -html=coverage.out -o coverage.html
    

Test Strategy

Unit Tests to Verify:

  • backend/internal/services/security_service_test.go (password hashing/verification)
  • backend/internal/models/user_test.go (User model password operations)

Integration Tests:

  • User registration flow (POST /api/v1/users)
  • User login flow (POST /api/v1/auth/login)
  • Password reset flow (if implemented)

Expected Coverage: Maintain or exceed current 85% threshold.


1.2 expr-lang/expr Upgrade (Caddy - ALREADY FIXED)

Current Usage Analysis

Direct Usage: None in backend Go code.

Transitive Usage: expr-lang/expr is used by Caddy plugins (via crowdsec-bouncer, coraza-caddy, security plugins).

Location in Codebase:

  • Dockerfile line 181: Already patches to v1.17.7 during Caddy build
  • CI verification: .github/workflows/docker-build.yml lines 157-217

Current Mitigation Status: ALREADY IMPLEMENTED

The Dockerfile already includes this fix:

# renovate: datasource=go depName=github.com/expr-lang/expr
go get github.com/expr-lang/expr@v1.17.7; \

CVE: CVE-2025-68156 (GHSA-cfpf-hrx2-8rv6)

Verification Steps

  1. Confirm Dockerfile contains fix:

    grep -A1 "expr-lang/expr" Dockerfile
    

    Expected output: go get github.com/expr-lang/expr@v1.17.7

  2. Rebuild Docker image:

    docker build --no-cache -t charon:vuln-test .
    
  3. Extract Caddy binary and verify:

    docker run --rm --entrypoint sh charon:vuln-test -c "cat /usr/bin/caddy" > caddy_binary
    go version -m caddy_binary | grep expr-lang
    

    Expected: github.com/expr-lang/expr v1.17.7

  4. Run Docker build verification job:

    # Triggers CI job with expr-lang verification
    git push origin main
    

Test Strategy

No additional backend testing required - this is a Caddy/Docker-level fix.

Docker Integration Tests:

  • Task: Integration: Coraza WAF (uses expr-lang for rule evaluation)
  • Task: Integration: CrowdSec (bouncer plugin uses expr-lang)
  • Task: Integration: Run All

Expected Result: All integration tests pass with v1.17.7 binary.


1.3 expr-lang/expr Upgrade (CrowdSec - REQUIRES PATCHING)

Current Problem

Location: CrowdSec binaries (crowdsec, cscli) built in Dockerfile lines 199-244

Current State:

  • CrowdSec IS built from source (not downloaded pre-compiled)
  • Uses Go 1.25.5+ to avoid stdlib vulnerabilities
  • DOES NOT patch expr-lang/expr dependency before build
  • Binaries contain vulnerable expr-lang/expr v1.17.2

Impact:

CrowdSec uses expr-lang/expr extensively for:

  • Scenario evaluation (attack pattern matching)
  • Parser filters (log parsing conditional logic)
  • Whitelist expressions (decision exceptions)
  • Conditional rule execution

CVE-2025-68156 could allow:

  • Arbitrary code execution via crafted scenarios
  • Denial of service through malicious expressions
  • Security bypass in rule evaluation

Implementation Required

File: Dockerfile

Location: Lines 199-244 (crowdsec-builder stage)

Change: Add expr-lang/expr patch step after git clone and before go build commands.

Required Addition (after line 223):

# Patch expr-lang/expr dependency to fix CVE-2025-68156
# This follows the same pattern as Caddy's expr-lang patch (Dockerfile line 181)
# renovate: datasource=go depName=github.com/expr-lang/expr
RUN go get github.com/expr-lang/expr@v1.17.7 && \
    go mod tidy

Update Comment (line 225):

# OLD:
# Build CrowdSec binaries for target architecture

# NEW:
# Build CrowdSec binaries for target architecture with patched dependencies

See Detailed Plan: docs/plans/crowdsec_source_build.md for complete implementation guide.

Verification Steps

  1. Build Docker image:

    docker build --no-cache -t charon:crowdsec-patch .
    
  2. Extract cscli binary:

    docker create --name crowdsec-verify charon:crowdsec-patch
    docker cp crowdsec-verify:/usr/local/bin/cscli ./cscli_binary
    docker rm crowdsec-verify
    
  3. Verify expr-lang version:

    go version -m ./cscli_binary | grep expr-lang
    

    Expected: github.com/expr-lang/expr v1.17.7

  4. Run CrowdSec integration tests:

    .github/skills/scripts/skill-runner.sh integration-test-crowdsec
    

Test Strategy

Integration Tests:

  • Task: Integration: CrowdSec (full CrowdSec functionality)
  • Task: Integration: CrowdSec Startup (first-time initialization)
  • Task: Integration: CrowdSec Decisions (decision API)
  • Task: Integration: Coraza WAF (indirect test - WAF uses expr-lang too)

Expected Result: All tests pass, no expr-lang evaluation errors in logs.


Phase 2: Dockerfile Base Image Update (MEDIUM PRIORITY)

2.1 Alpine Package CVEs Analysis

Current Alpine Version

Dockerfile line 22 and 246:

ARG CADDY_IMAGE=alpine:3.23
FROM alpine:3.23 AS crowdsec-fallback

Current Package Versions (from scan):

  • busybox: 1.37.0-r20
  • busybox-binsh: 1.37.0-r20
  • curl: 8.14.1-r2
  • ssl_client: 1.37.0-r20

Target Alpine Version Research

Investigation Required: Determine which Alpine version contains patched packages for CVE-2025-60876 and CVE-2025-10966.

Research Steps:

  1. Check Alpine 3.23 edge repository: https://pkgs.alpinelinux.org/packages?name=busybox&branch=v3.23
  2. Check Alpine 3.24 (next stable): https://pkgs.alpinelinux.org/packages?name=busybox&branch=v3.24
  3. Review Alpine security advisories: https://security.alpinelinux.org/

Expected Outcome: Either:

  • Option A: Update to Alpine 3.24 (if stable release available with patches)
  • Option B: Update to latest Alpine 3.23 digest (if patches backported)
  • Option C: Wait for Alpine security updates to 3.23 stable

Implementation Strategy

Current Dockerfile Already Includes Auto-Update Mechanism:

# Line 290 (Final runtime stage)
RUN apk --no-cache add bash ca-certificates sqlite-libs sqlite tzdata curl gettext su-exec libcap-utils \
    && apk --no-cache upgrade \
    && apk --no-cache upgrade c-ares

Key Insight: The apk upgrade command automatically pulls latest package versions from Alpine repos. No Dockerfile changes needed if packages are available in 3.23 repos.

Dockerfile Changes (if base image upgrade required)

If Alpine 3.24 is needed:

File: Dockerfile

Change 1: Update CADDY_IMAGE ARG (line 22)

# OLD
ARG CADDY_IMAGE=alpine:3.23

# NEW
ARG CADDY_IMAGE=alpine:3.24

Change 2: Update crowdsec-fallback base (line 246)

# OLD
FROM alpine:3.23 AS crowdsec-fallback

# NEW
FROM alpine:3.24 AS crowdsec-fallback

Change 3: Update final runtime base (line 284)

# OLD
FROM ${CADDY_IMAGE}

# NEW (no change needed - uses ARG)
FROM ${CADDY_IMAGE}

Change 4: Update Renovate tracking comments

# Line 20
# OLD
# renovate: datasource=docker depName=alpine
ARG CADDY_IMAGE=alpine:3.23

# NEW
# renovate: datasource=docker depName=alpine
ARG CADDY_IMAGE=alpine:3.24

Build and Test Strategy

Step 1: Force rebuild without cache

docker build --no-cache --progress=plain -t charon:alpine-update .

Step 2: Verify package versions

docker run --rm charon:alpine-update sh -c "apk info busybox curl ssl_client"

Expected: No CVE-2025-60876 or CVE-2025-10966 versions

Step 3: Run integration tests

# Start container
docker run -d --name charon-test -p 8080:8080 -p 80:80 -p 443:443 charon:alpine-update

# Wait for startup
sleep 30

# Run health check
curl -f http://localhost:8080/api/v1/health || exit 1

# Run full integration suite
.github/skills/scripts/skill-runner.sh integration-test-all

# Cleanup
docker rm -f charon-test

Step 4: GeoLite2 database download test

docker run --rm charon:alpine-update sh -c "test -f /app/data/geoip/GeoLite2-Country.mmdb && echo 'GeoLite2 DB exists' || echo 'ERROR: GeoLite2 DB missing'"

Expected: GeoLite2 DB exists

Step 5: CrowdSec binary verification

docker run --rm charon:alpine-update sh -c "cscli version || echo 'CrowdSec not installed (expected for non-amd64)'"

Expected: Version output or expected message


Phase 3: Validation & Testing

3.1 Unit Test Execution

Backend Tests (with coverage):

cd backend
go test -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -func=coverage.out

Coverage Requirements:

  • Overall: ≥85% (current threshold)
  • Patch coverage: 100% (Codecov requirement)
  • Critical packages (crypto, security): ≥90%

Expected Files with Coverage:

  • internal/services/security_service.go (bcrypt usage)
  • internal/models/user.go (password hashing)
  • internal/crypto/encryption.go (AES-GCM encryption)
  • internal/crowdsec/console_enroll.go (AES encryption for enrollment keys)

Frontend Tests:

cd frontend
npm run test:ci
npm run type-check
npm run lint

3.2 Integration Test Execution

Task Order (sequential):

  1. Backend Unit Tests:

    .vscode/tasks.json -> "Test: Backend with Coverage"
    

    Expected: All pass, coverage ≥85%

  2. Frontend Tests:

    .vscode/tasks.json -> "Test: Frontend with Coverage"
    

    Expected: All pass, coverage report generated

  3. Docker Build:

    .vscode/tasks.json -> "Build & Run: Local Docker Image"
    

    Expected: Build succeeds, container starts

  4. Integration Tests:

    .vscode/tasks.json -> "Integration: Run All"
    

    Runs:

    • Coraza WAF tests (expr-lang usage)
    • CrowdSec integration tests
    • CrowdSec decisions API tests
    • CrowdSec startup tests
  5. Security Scans:

    .vscode/tasks.json -> "Security: Go Vulnerability Check"
    

    Expected: Zero HIGH/CRITICAL vulnerabilities

3.3 Security Scan Re-run

Step 1: Trivy Image Scan

docker build -t charon:patched .
trivy image --severity HIGH,CRITICAL charon:patched > trivy-post-fix.txt

Step 2: govulncheck (Go modules)

cd backend
govulncheck ./... > govulncheck-post-fix.txt

Step 3: Compare Results

# Check for remaining vulnerabilities
grep -E "CVE-2025-(60876|10966)|GHSA-(cfpf-hrx2-8rv6|j5w8-q4qc-rx2x|f6x5-jh6r-wrfv)" trivy-post-fix.txt

Expected: No matches

Step 4: SBOM Verification

.vscode/tasks.json -> "Security: Verify SBOM"
# Input when prompted: charon:patched

3.4 Docker Image Functionality Verification

Smoke Test Checklist:

  • Container starts without errors
  • Caddy web server responds on port 80
  • Charon API responds on port 8080
  • Frontend loads in browser (http://localhost)
  • User can log in
  • Proxy host creation works
  • Caddy config reloads successfully
  • CrowdSec (if enabled) starts without errors
  • Logs show no critical errors

Full Functionality Test:

# Start container
docker run -d --name charon-smoke-test \
  -p 8080:8080 -p 80:80 -p 443:443 \
  -v charon-test-data:/app/data \
  charon:patched

# Wait for startup
sleep 30

# Run smoke tests
curl -f http://localhost:8080/api/v1/health
curl -f http://localhost
curl -f http://localhost:8080/api/v1/version

# Check logs
docker logs charon-smoke-test | grep -i error
docker logs charon-smoke-test | grep -i fatal
docker logs charon-smoke-test | grep -i panic

# Cleanup
docker rm -f charon-smoke-test
docker volume rm charon-test-data

Phase 4: Configuration File Review & Updates

4.1 .gitignore Review

Current Status: Already comprehensive

Key Patterns Verified:

  • *.sarif (excludes security scan results)
  • *.cover (excludes coverage artifacts)
  • codeql-db*/ (excludes CodeQL databases)
  • trivy-*.txt (excludes Trivy scan outputs)

Recommendation: No changes needed.

4.2 .dockerignore Review

Current Status: Already optimized

Key Exclusions Verified:

  • codeql-db/ (security scan artifacts)
  • *.sarif (security results)
  • *.cover (coverage files)
  • trivy-*.txt (scan outputs)

Recommendation: No changes needed.

4.3 codecov.yml Configuration

Current Status: ⚠️ FILE NOT FOUND

Expected Location: /projects/Charon/codecov.yml or /projects/Charon/.codecov.yml

Investigation Required: Check if Codecov uses default configuration or if file is in different location.

Recommended Action: If coverage thresholds need adjustment after upgrades, create:

File: codecov.yml

coverage:
  status:
    project:
      default:
        target: 85%           # Overall project coverage
        threshold: 1%         # Allow 1% drop
    patch:
      default:
        target: 100%          # New code must be fully covered
        threshold: 0%         # No tolerance for uncovered new code

ignore:
  - "**/*_test.go"
  - "**/test_*.go"
  - "**/*.test.tsx"
  - "**/*.spec.ts"
  - "frontend/src/setupTests.ts"

comment:
  layout: "header, diff, files"
  behavior: default
  require_changes: false

Action: Create this file only if Codecov fails validation after upgrades.

4.4 Dockerfile Review

Files: Dockerfile, .docker/docker-entrypoint.sh

Changes Required: See Phase 2.1 (Alpine base image update)

Additional Checks:

  1. Renovate tracking comments - Ensure all version pins have renovate comments:

    # renovate: datasource=go depName=github.com/expr-lang/expr
    # renovate: datasource=docker depName=alpine
    # renovate: datasource=github-releases depName=crowdsecurity/crowdsec
    
  2. Multi-stage build cache - Verify cache mount points still valid:

    RUN --mount=type=cache,target=/root/.cache/go-build
    RUN --mount=type=cache,target=/go/pkg/mod
    RUN --mount=type=cache,target=/app/frontend/node_modules/.cache
    
  3. Security hardening - Confirm no regression:

    • Non-root user (charon:1000)
    • CAP_NET_BIND_SERVICE for Caddy
    • Minimal package installation
    • Regular apk upgrade

Detailed Task Breakdown

Task 1: Research & Verify CVE Details (30 mins)

Owner: Security Team / Lead Developer Dependencies: None

Steps:

  1. Research golang.org/x/crypto CVEs (GHSA-j5w8-q4qc-rx2x, GHSA-f6x5-jh6r-wrfv)

    • Verify if CVEs apply to bcrypt usage
    • Determine correct target version
    • Check if v0.46.0 already contains fixes
  2. Research Alpine CVEs (CVE-2025-60876, CVE-2025-10966)

    • Check Alpine 3.23 package repository for updates
    • Check Alpine 3.24 availability and package versions
    • Document target Alpine version

Deliverables:

  • CVE research notes with findings
  • Target versions for each package
  • Decision: Stay on Alpine 3.23 or upgrade to 3.24

Task 2: Verify/Update Go Modules (30 mins - May be NOOP)

Owner: Backend Developer Dependencies: Task 1 (CVE research)

Files:

  • backend/go.mod
  • backend/go.sum

Step 1: Verify CVE applicability

cd backend

# Run govulncheck to verify if CVEs are real
go run golang.org/x/vuln/cmd/govulncheck@latest ./...

Step 2: Update if needed (conditional)

# ONLY if govulncheck reports vulnerabilities:
go get -u golang.org/x/crypto@latest
go mod tidy
git diff go.mod go.sum

Step 3: Document findings

# If NO vulnerabilities found:
echo "golang.org/x/crypto v0.46.0 - No vulnerabilities detected (false positive confirmed)" >> task2_findings.txt

# If vulnerabilities found and patched:
echo "golang.org/x/crypto upgraded from v0.46.0 to v0.XX.X" >> task2_findings.txt

Testing:

# Run all backend tests
go test ./... -v

# Run with coverage
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | tail -1
# Expected: total coverage ≥85%

# Run security scan
go run golang.org/x/vuln/cmd/govulncheck@latest ./...
# Expected: No vulnerabilities in golang.org/x/crypto

Verification:

  • go.mod shows updated golang.org/x/crypto version
  • All backend tests pass
  • Coverage ≥85%
  • govulncheck reports no vulnerabilities
  • No unexpected dependency changes

Rollback Plan:

git checkout backend/go.mod backend/go.sum
cd backend && go mod download

Task 3: Verify expr-lang/expr Fix in Caddy (15 mins)

Owner: DevOps / Docker Specialist Dependencies: None (already implemented)

File: Dockerfile

Steps:

  1. Verify line 181 contains:

    # renovate: datasource=go depName=github.com/expr-lang/expr
    go get github.com/expr-lang/expr@v1.17.7; \
    
  2. Confirm CI workflow verification (lines 157-217 of .github/workflows/docker-build.yml)

Testing:

# Local build with verification
docker build --target caddy-builder -t caddy-test .

# Extract Caddy binary
docker create --name caddy-temp caddy-test
docker cp caddy-temp:/usr/bin/caddy ./caddy_binary
docker rm caddy-temp

# Verify version (requires Go toolchain)
go version -m ./caddy_binary | grep expr-lang
# Expected: github.com/expr-lang/expr v1.17.7

rm ./caddy_binary

Verification:

  • Dockerfile contains v1.17.7 reference
  • CI workflow contains verification logic
  • Local build extracts binary successfully
  • Binary contains v1.17.7 (if Go toolchain available)

Notes:

  • No changes needed (already implemented)
  • This task is verification only

Task 3B: Add expr-lang/expr Patch to CrowdSec (90 mins)

Owner: DevOps / Docker Specialist Dependencies: None

File: Dockerfile

Location: Lines 199-244 (crowdsec-builder stage)

Implementation:

Step 1: Add expr-lang patch (after line 223)

Insert between git clone and first go build:

# Patch expr-lang/expr dependency to fix CVE-2025-68156
# This follows the same pattern as Caddy's expr-lang patch (Dockerfile line 181)
# renovate: datasource=go depName=github.com/expr-lang/expr
RUN go get github.com/expr-lang/expr@v1.17.7 && \
    go mod tidy

Step 2: Update build comment (line 225)

# OLD:
# Build CrowdSec binaries for target architecture

# NEW:
# Build CrowdSec binaries for target architecture with patched dependencies

Step 3: Update top-level comments (line ~7-17)

Add security patch documentation:

## Security Patches:
## - Caddy: expr-lang/expr@v1.17.7 (CVE-2025-68156)
## - CrowdSec: expr-lang/expr@v1.17.7 (CVE-2025-68156)

Commands:

# Edit Dockerfile
vim Dockerfile

# Build with no cache to verify patch
docker build --no-cache --progress=plain -t charon:crowdsec-patch . 2>&1 | tee build.log

# Check build log for patch step
grep -A3 "expr-lang/expr" build.log

# Extract and verify cscli binary
docker create --name crowdsec-verify charon:crowdsec-patch
docker cp crowdsec-verify:/usr/local/bin/cscli ./cscli_binary
docker rm crowdsec-verify

# Verify expr-lang version (requires Go)
go version -m ./cscli_binary | grep expr-lang
# Expected: github.com/expr-lang/expr v1.17.7

rm ./cscli_binary

Verification:

  • Dockerfile patch added after line 223
  • Build succeeds without errors
  • Build log shows "go get github.com/expr-lang/expr@v1.17.7"
  • cscli binary contains expr-lang v1.17.7
  • crowdsec binary contains expr-lang v1.17.7 (optional check)
  • Renovate tracking comment present

Rollback Plan:

git diff HEAD Dockerfile > /tmp/crowdsec_patch.diff
git checkout Dockerfile
docker build -t charon:rollback .

See Also: docs/plans/crowdsec_source_build.md for complete implementation guide.


Task 4: Update Dockerfile Alpine Base Image (30 mins)

Owner: DevOps / Docker Specialist Dependencies: Task 1 (Alpine version research)

File: Dockerfile

Changes:

Scenario A: Stay on Alpine 3.23 (packages available)

  • No changes needed
  • apk upgrade will pull patched packages automatically

Scenario B: Upgrade to Alpine 3.24

# Line 20-22
- # renovate: datasource=docker depName=alpine
- ARG CADDY_IMAGE=alpine:3.23
+ # renovate: datasource=docker depName=alpine
+ ARG CADDY_IMAGE=alpine:3.24

# Line 246
- FROM alpine:3.23 AS crowdsec-fallback
+ FROM alpine:3.24 AS crowdsec-fallback

Commands:

# Edit Dockerfile
vim Dockerfile

# Build with no cache to force package updates
docker build --no-cache --progress=plain -t charon:alpine-patched .

# Verify Alpine version
docker run --rm charon:alpine-patched cat /etc/alpine-release
# Expected: 3.24.x (if Scenario B) or 3.23.x (if Scenario A)

# Verify package versions
docker run --rm charon:alpine-patched sh -c "apk info busybox curl ssl_client"

Verification:

  • Dockerfile updated (if Scenario B)
  • Build succeeds without errors
  • Alpine version matches expectation
  • Package versions contain security patches
  • No CVE-2025-60876 or CVE-2025-10966 detected

Rollback Plan:

git checkout Dockerfile
docker build -t charon:latest .

Task 5: Run Backend Tests with Coverage (45 mins)

Owner: Backend Developer Dependencies: Task 2 (Go module updates)

Commands:

cd backend

# Run all tests with coverage
go test -coverprofile=coverage.out -covermode=atomic ./...

# Generate HTML report
go tool cover -html=coverage.out -o coverage.html

# Check overall coverage
go tool cover -func=coverage.out | tail -1

# Check specific files
go tool cover -func=coverage.out | grep -E "(security_service|user\.go|encryption\.go|console_enroll\.go)"

VS Code Task:

// Use existing task: "Test: Backend with Coverage"
// Location: .vscode/tasks.json

Expected Results:

backend/internal/services/security_service.go:    ≥90.0%
backend/internal/models/user.go:                  ≥85.0%
backend/internal/crypto/encryption.go:            ≥95.0%
backend/internal/crowdsec/console_enroll.go:      ≥85.0%

TOTAL COVERAGE:                                   ≥85.0%

Critical Test Files:

  • security_service_test.go (bcrypt password hashing)
  • user_test.go (User model password operations)
  • encryption_test.go (AES-GCM encryption)
  • console_enroll_test.go (enrollment key encryption)

Verification:

  • All tests pass
  • Total coverage ≥85%
  • No new uncovered lines in modified files
  • Critical security functions (bcrypt, encryption) have high coverage (≥90%)
  • coverage.html generated for review

Task 6: Run Frontend Tests (30 mins)

Owner: Frontend Developer Dependencies: None (independent of backend changes)

Commands:

cd frontend

# Install dependencies (if needed)
npm ci

# Run type checking
npm run type-check

# Run linting
npm run lint

# Run tests with coverage
npm run test:ci

# Generate coverage report
npm run coverage

VS Code Tasks:

// Use existing tasks:
// 1. "Lint: TypeScript Check"
// 2. "Lint: Frontend"
// 3. "Test: Frontend with Coverage"

Expected Results:

  • TypeScript: 0 errors
  • ESLint: 0 errors, 0 warnings
  • Tests: All pass
  • Coverage: ≥80% (standard frontend threshold)

Verification:

  • TypeScript compilation succeeds
  • ESLint shows no errors
  • All frontend tests pass
  • Coverage report generated
  • No regressions in existing tests

Task 7: Build Docker Image (30 mins)

Owner: DevOps / Docker Specialist Dependencies: Task 4 (Dockerfile updates)

Commands:

# Build with no cache to ensure fresh packages
docker build --no-cache --progress=plain -t charon:security-patch .

# Tag for testing
docker tag charon:security-patch charon:test

# Verify image size (should be similar to previous builds)
docker images | grep charon

VS Code Task:

// Use existing task: "Build & Run: Local Docker Image No-Cache"

Build Verification:

# Check Alpine version
docker run --rm charon:test cat /etc/alpine-release

# Check package versions
docker run --rm charon:test apk info busybox curl ssl_client c-ares

# Check Caddy version
docker run --rm --entrypoint caddy charon:test version

# Check CrowdSec version
docker run --rm --entrypoint cscli charon:test version || echo "CrowdSec not installed (expected for non-amd64)"

# Check GeoLite2 database
docker run --rm charon:test test -f /app/data/geoip/GeoLite2-Country.mmdb && echo "OK" || echo "MISSING"

Expected Build Time:

  • First build (no cache): 15-20 mins
  • Subsequent builds (with cache): 3-5 mins

Verification:

  • Build completes without errors
  • Image size reasonable (< 500MB)
  • Alpine packages updated
  • Caddy binary includes expr-lang v1.17.7
  • GeoLite2 database downloaded
  • CrowdSec binaries present (amd64) or placeholder (other archs)

Task 8: Run Integration Tests (60 mins)

Owner: QA / Integration Specialist Dependencies: Task 7 (Docker image build)

Test Sequence:

8.1 Coraza WAF Integration (15 mins)

.vscode/tasks.json -> "Integration: Coraza WAF"
# Or:
.github/skills/scripts/skill-runner.sh integration-test-coraza

What It Tests:

  • Caddy + Coraza plugin integration
  • expr-lang/expr usage in WAF rule evaluation
  • HTTP request filtering
  • Security rule processing

Expected Results:

  • Container starts successfully
  • Coraza WAF loads rules
  • Test requests blocked/allowed correctly
  • No expr-lang errors in logs

8.2 CrowdSec Integration (20 mins)

.vscode/tasks.json -> "Integration: CrowdSec"
# Or:
.github/skills/scripts/skill-runner.sh integration-test-crowdsec

What It Tests:

  • CrowdSec binary execution
  • Hub item installation
  • Bouncer registration
  • Log parsing and decision making

Expected Results:

  • CrowdSec starts without errors
  • Hub items install successfully
  • Bouncer registered
  • Sample attacks detected

8.3 CrowdSec Decisions API (10 mins)

.vscode/tasks.json -> "Integration: CrowdSec Decisions"
# Or:
.github/skills/scripts/skill-runner.sh integration-test-crowdsec-decisions

What It Tests:

  • Decisions API endpoint
  • Manual decision creation
  • Decision expiration
  • IP blocking

8.4 CrowdSec Startup (15 mins)

.vscode/tasks.json -> "Integration: CrowdSec Startup"
# Or:
.github/skills/scripts/skill-runner.sh integration-test-crowdsec-startup

What It Tests:

  • First-time CrowdSec initialization
  • Configuration generation
  • Database creation
  • Clean startup sequence

8.5 Full Integration Suite (runs all above)

.vscode/tasks.json -> "Integration: Run All"
# Or:
.github/skills/scripts/skill-runner.sh integration-test-all

Verification:

  • Coraza WAF tests pass
  • CrowdSec tests pass
  • CrowdSec Decisions tests pass
  • CrowdSec Startup tests pass
  • No critical errors in logs
  • Container health checks pass

Troubleshooting: If tests fail:

  1. Check container logs: docker logs <container-id>
  2. Check Caddy logs: docker exec <container-id> cat /var/log/caddy/access.log
  3. Check CrowdSec logs: docker exec <container-id> cat /var/log/crowdsec/crowdsec.log
  4. Verify package versions: docker exec <container-id> apk info busybox curl ssl_client

Task 9: Security Scan Verification (30 mins)

Owner: Security Team Dependencies: Task 7 (Docker image build)

9.1 Trivy Image Scan

# Scan for HIGH and CRITICAL vulnerabilities
trivy image --severity HIGH,CRITICAL charon:test

# Generate detailed report
trivy image --severity HIGH,CRITICAL --format json --output trivy-post-patch.json charon:test

# Compare with pre-patch scan
diff <(jq '.Results[].Vulnerabilities[].VulnerabilityID' trivy-pre-patch.json | sort) \
     <(jq '.Results[].Vulnerabilities[].VulnerabilityID' trivy-post-patch.json | sort)

VS Code Task:

// Use existing task: "Security: Trivy Scan"

Expected Results:

✅ No HIGH or CRITICAL vulnerabilities found
✅ CVE-2025-60876 not detected (busybox, busybox-binsh, ssl_client)
✅ CVE-2025-10966 not detected (curl)

9.2 Go Vulnerability Check

cd backend
go run golang.org/x/vuln/cmd/govulncheck@latest ./...

VS Code Task:

// Use existing task: "Security: Go Vulnerability Check"

Expected Results:

✅ No vulnerabilities found
✅ GHSA-cfpf-hrx2-8rv6 not detected (expr-lang/expr via Caddy - already patched)
✅ GHSA-j5w8-q4qc-rx2x not detected (golang.org/x/crypto)
✅ GHSA-f6x5-jh6r-wrfv not detected (golang.org/x/crypto)

9.3 SBOM Verification

# Generate SBOM for patched image
docker sbom charon:test --output sbom-post-patch.json

# Verify SBOM contains updated packages
.vscode/tasks.json -> "Security: Verify SBOM"
# Input: charon:test

Expected SBOM Contents:

9.4 CodeQL Scan (Optional - runs in CI)

# Go scan
.vscode/tasks.json -> "Security: CodeQL Go Scan (CI-Aligned) [~60s]"

# JavaScript/TypeScript scan
.vscode/tasks.json -> "Security: CodeQL JS Scan (CI-Aligned) [~90s]"

# Or run both
.vscode/tasks.json -> "Security: CodeQL All (CI-Aligned)"

Expected Results:

  • No new CodeQL findings
  • Existing findings remain addressed
  • No regression in security posture

Verification:

  • Trivy scan shows zero HIGH/CRITICAL vulnerabilities
  • govulncheck reports no Go module vulnerabilities
  • SBOM contains updated package versions
  • CodeQL scans pass (if run)
  • All target CVEs confirmed fixed

Task 10: Docker Image Functionality Smoke Test (45 mins)

Owner: QA / Integration Specialist Dependencies: Task 7 (Docker image build)

10.1 Container Startup Test

# Start container
docker run -d \
  --name charon-smoke-test \
  -p 8080:8080 \
  -p 80:80 \
  -p 443:443 \
  -v charon-smoke-data:/app/data \
  charon:test

# Wait for full startup (Caddy + Charon + CrowdSec)
sleep 45

# Check container is running
docker ps | grep charon-smoke-test

Verification:

  • Container starts without errors
  • Container stays running (not restarting)
  • Health check passes: docker inspect --format='{{.State.Health.Status}}' charon-smoke-test

10.2 API Endpoint Tests

# Health endpoint
curl -f http://localhost:8080/api/v1/health
# Expected: {"status": "healthy"}

# Version endpoint
curl -f http://localhost:8080/api/v1/version
# Expected: {"version": "...", "build_time": "...", "commit": "..."}

# Setup status (initial)
curl -f http://localhost:8080/api/v1/setup
# Expected: {"setupRequired": true} (first run)

# Frontend static files
curl -I http://localhost
# Expected: 200 OK

Verification:

  • Health endpoint returns healthy status
  • Version endpoint returns version info
  • Setup endpoint responds
  • Frontend loads (returns 200)

10.3 Frontend Load Test

# Test frontend loads in browser (manual step)
# Open: http://localhost

# Or use curl to verify critical resources
curl -I http://localhost/assets/index.js
curl -I http://localhost/assets/index.css

Manual Verification:

  • Browser loads frontend without errors
  • No console errors in browser DevTools
  • Login page displays correctly
  • Navigation menu visible

10.4 User Authentication Test

# Create initial admin user (via API)
curl -X POST http://localhost:8080/api/v1/setup \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Admin",
    "email": "admin@test.local",
    "password": "TestPassword123!"
  }'

# Login
curl -X POST http://localhost:8080/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@test.local",
    "password": "TestPassword123!"
  }' \
  -c cookies.txt

# Verify session (using saved cookies)
curl -b cookies.txt http://localhost:8080/api/v1/users/me

Verification:

  • Admin user created successfully
  • Login returns JWT token
  • Session authentication works
  • bcrypt password hashing functioning (golang.org/x/crypto)

10.5 Proxy Host Operations Test

# Create test proxy host (requires authentication)
curl -X POST http://localhost:8080/api/v1/proxy-hosts \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "domain_names": ["test.local"],
    "forward_scheme": "http",
    "forward_host": "127.0.0.1",
    "forward_port": 8000,
    "enabled": true
  }'

# List proxy hosts
curl -b cookies.txt http://localhost:8080/api/v1/proxy-hosts

# Get Caddy config (verify reload)
curl http://localhost:2019/config/

Verification:

  • Proxy host created successfully
  • Caddy config updated
  • No errors in Caddy logs
  • Caddy Admin API responding

10.6 Log Analysis

# Check for critical errors
docker logs charon-smoke-test 2>&1 | grep -iE "(error|fatal|panic|failed)" | head -20

# Check Caddy startup
docker logs charon-smoke-test 2>&1 | grep -i caddy | head -10

# Check CrowdSec startup (if enabled)
docker logs charon-smoke-test 2>&1 | grep -i crowdsec | head -10

# Check for CVE-related errors (should be none)
docker logs charon-smoke-test 2>&1 | grep -iE "(CVE-2025|vulnerability|security)"

Verification:

  • No critical errors in logs
  • Caddy started successfully
  • CrowdSec started successfully (if applicable)
  • No security warnings related to patched CVEs

10.7 Cleanup

# Stop and remove container
docker stop charon-smoke-test
docker rm charon-smoke-test

# Remove test data
docker volume rm charon-smoke-data

# Clean up cookies
rm cookies.txt

Final Smoke Test Checklist:

  • Container startup successful
  • API endpoints functional
  • Frontend loads correctly
  • Authentication works (bcrypt functioning)
  • Proxy host CRUD operations functional
  • Caddy config reloads successful
  • CrowdSec operational (if enabled)
  • No critical errors in logs
  • All patched packages functioning correctly

Rollback Procedures

Rollback Scenario 1: Go Module Update Breaks Tests

Symptoms:

  • Backend tests fail after golang.org/x/crypto update
  • bcrypt password hashing errors
  • Compilation errors

Rollback Steps:

cd backend

# Revert go.mod and go.sum
git checkout go.mod go.sum

# Download dependencies
go mod download

# Verify tests pass
go test ./...

# Commit rollback
git add go.mod go.sum
git commit -m "revert: rollback golang.org/x/crypto update due to test failures"

Post-Rollback:

  • Document failure reason
  • Investigate CVE applicability to current version
  • Consider requesting CVE false positive review

Rollback Scenario 2: Alpine Update Breaks Container

Symptoms:

  • Container fails to start
  • Missing packages
  • curl or busybox errors

Rollback Steps:

# Revert Dockerfile
git checkout Dockerfile

# Rebuild with old Alpine version
docker build --no-cache -t charon:rollback .

# Test rollback image
docker run -d --name charon-rollback-test charon:rollback
docker logs charon-rollback-test
docker stop charon-rollback-test
docker rm charon-rollback-test

# If successful, commit rollback
git add Dockerfile
git commit -m "revert: rollback Alpine base image update due to container failures"

Post-Rollback:

  • Document specific package causing issue
  • Check Alpine issue tracker
  • Consider waiting for next Alpine point release

Rollback Scenario 3: Integration Tests Fail

Symptoms:

  • Coraza WAF tests fail
  • CrowdSec integration broken
  • expr-lang errors in logs

Rollback Steps:

# Revert all changes
git reset --hard HEAD~1

# Or revert specific commits
git revert <commit-hash>

# Rebuild known-good image
docker build -t charon:rollback .

# Run integration tests
.github/skills/scripts/skill-runner.sh integration-test-all

Post-Rollback:

  • Analyze integration test logs
  • Identify root cause (Caddy plugin? CrowdSec compatibility?)
  • Consider phased rollout instead of full update

Success Criteria

Critical Success Metrics

  1. Zero HIGH/CRITICAL Vulnerabilities:

    • Trivy scan: 0 HIGH, 0 CRITICAL
    • govulncheck: 0 vulnerabilities
  2. All Tests Pass:

    • Backend unit tests: 100% pass rate
    • Frontend tests: 100% pass rate
    • Integration tests: 100% pass rate
  3. Coverage Maintained:

    • Backend overall: ≥85%
    • Backend critical packages: ≥90%
    • Frontend: ≥80%
    • Patch coverage: 100%
  4. Functional Verification:

    • Container starts successfully
    • API responds to health checks
    • Frontend loads in browser
    • User authentication works
    • Proxy host creation functional

Secondary Success Metrics

  1. Build Performance:

    • Build time < 20 mins (no cache)
    • Build time < 5 mins (with cache)
    • Image size < 500MB
  2. Integration Stability:

    • Coraza WAF functional
    • CrowdSec operational
    • expr-lang no errors
    • No log errors/warnings
  3. CI/CD Validation:

    • GitHub Actions pass
    • CodeQL scans clean
    • SBOM generation successful
    • Security scan automated

Timeline & Resource Allocation

Estimated Timeline (Total: 8 hours)

Phase Duration Parallel? Critical Path?
Task 1: CVE Research 30 mins No Yes
Task 2: Go Module Verification 30 mins No Yes (conditional)
Task 3: Caddy expr-lang Verification 15 mins Yes (with Task 2) No
Task 3B: CrowdSec expr-lang Patch 90 mins No Yes
Task 4: Dockerfile Alpine Updates 30 mins No Yes (conditional)
Task 5: Backend Tests 45 mins No Yes
Task 6: Frontend Tests 30 mins Yes (with Task 5) No
Task 7: Docker Build 30 mins No Yes
Task 8: Integration Tests 90 mins No Yes (includes CrowdSec tests)
Task 9: Security Scans 45 mins Yes (with Task 8) Yes
Task 10: Smoke Tests 45 mins No Yes

Critical Path: Tasks 1 → 2 → 3B → 4 → 5 → 7 → 8 → 9 → 10 = 7 hours

Optimized with Parallelization:

  • Run Task 3 during Task 2
  • Run Task 6 during Task 5
  • Run Task 9 partially during Task 8

Total Optimized Time: ~6-7 hours

Key Addition: Task 3B (CrowdSec expr-lang patch) is the major new work item requiring 90 minutes.

Resource Requirements

Personnel:

  • 1x Backend Developer (Tasks 2, 5)
  • 1x Frontend Developer (Task 6)
  • 1x DevOps Engineer (Tasks 3, 3B, 4, 7) - Primary owner of critical CrowdSec patch
  • 1x QA Engineer (Tasks 8, 10)
  • 1x Security Specialist (Tasks 1, 9)

Infrastructure:

  • Development machine with Docker
  • Go 1.25+ toolchain
  • Node.js 24+ for frontend
  • 20GB disk space for Docker images
  • GitHub Actions runners (for CI validation)

Tools Required:

  • Docker Desktop / Docker CLI
  • Go toolchain
  • Node.js / npm
  • trivy (security scanner)
  • govulncheck (Go vulnerability scanner)
  • Git

Post-Remediation Actions

Immediate (Within 24 hours)

  1. Tag Release:

    git tag -a v1.x.x-security-patch -m "Security patch: Fix CVE-2025-68156 (expr-lang), CVE-2025-60876 (busybox), CVE-2025-10966 (curl)"
    git push origin v1.x.x-security-patch
    
  2. Update CHANGELOG.md:

    ## [v1.x.x-security-patch] - 2026-01-11
    
    ### Security Fixes
    - **fix(security)**: Patched expr-lang/expr v1.17.7 in CrowdSec binaries (CVE-2025-68156, GHSA-cfpf-hrx2-8rv6)
    - **fix(security)**: Verified expr-lang/expr v1.17.7 in Caddy build (CVE-2025-68156, already implemented)
    - **fix(security)**: Upgraded Alpine base image packages (CVE-2025-60876, CVE-2025-10966)
    - **fix(security)**: Verified golang.org/x/crypto v0.46.0 (no vulnerabilities found - false positive)
    
    ### Testing
    - All backend tests pass with ≥85% coverage
    - All frontend tests pass
    - Integration tests (Coraza WAF, CrowdSec) pass with patched binaries
    - Security scans show zero HIGH/CRITICAL vulnerabilities
    - CrowdSec functionality verified with expr-lang v1.17.7
    
  3. Publish Release Notes:

    • GitHub release with security advisory references
    • Docker Hub description update
    • Documentation site notice

Short-term (Within 1 week)

  1. Monitor for Regressions:

    • Check GitHub Issues for new bug reports
    • Monitor Docker Hub pull stats
    • Review CI/CD pipeline health
  2. Update Security Documentation:

    • Document patched CVEs in SECURITY.md
    • Update vulnerability disclosure policy
    • Add to security best practices
  3. Dependency Audit:

    • Review all Go module dependencies
    • Check for other outdated packages
    • Update Renovate configuration

Long-term (Within 1 month)

  1. Automated Security Scanning:

    • Enable Dependabot security updates
    • Configure Trivy scheduled scans
    • Set up CVE monitoring alerts
  2. Container Hardening Review:

    • Consider distroless base images
    • Minimize installed packages
    • Review network exposure
  3. Security Training:

    • Document lessons learned
    • Share with development team
    • Update security review checklist

Communication Plan

Internal Communication

Stakeholders:

  • Development Team
  • QA Team
  • DevOps Team
  • Security Team
  • Product Management

Communication Channels:

  • Slack: #security-updates
  • GitHub: Issue tracker
  • Email: security mailing list

External Communication

Channels:

  • GitHub Security Advisory (if required)
  • Docker Hub release notes
  • Documentation site banner
  • User mailing list (if exists)

Template Message:

Subject: Security Update - Charon v1.x.x Released

Dear Charon Users,

We have released Charon v1.x.x with critical security updates addressing:
- CVE-2025-60876 (busybox, ssl_client)
- CVE-2025-10966 (curl)
- GHSA-cfpf-hrx2-8rv6 (expr-lang)

All users are recommended to upgrade immediately:

Docker:
  docker pull ghcr.io/wikid82/charon:latest

Git:
  git pull origin main
  git checkout v1.x.x-security-patch

For full release notes and upgrade instructions, see:
https://github.com/Wikid82/charon/releases/tag/v1.x.x-security-patch

Questions? Contact: security@charon-project.io

The Charon Security Team

Appendix A: CVE Details

CVE-2025-68156 / GHSA-cfpf-hrx2-8rv6 (expr-lang/expr)

Package: github.com/expr-lang/expr Affected Versions: < v1.17.7 Fixed Version: v1.17.7 Severity: HIGH CVSS Score: 7.5+

Description: Expression evaluator vulnerability allowing arbitrary code execution or denial of service through crafted expressions.

Charon Impact (Dual Exposure):

  1. Caddy Binaries (FIXED):

    • Transitive dependency via Caddy security plugins (Coraza WAF, CrowdSec bouncer, caddy-security)
    • Affects WAF rule evaluation and bouncer decision logic
    • Status: Patched in Dockerfile line 181
    • CI Verification: Lines 157-217 of .github/workflows/docker-build.yml
  2. CrowdSec Binaries (REQUIRES FIX):

    • Direct dependency in CrowdSec scenarios, parsers, and whitelist expressions
    • Affects attack detection logic, log parsing filters, and decision exceptions
    • Status: Not yet patched (Dockerfile builds CrowdSec without patching expr-lang)
    • Mitigation: See docs/plans/crowdsec_source_build.md for implementation plan

GHSA-j5w8-q4qc-rx2x, GHSA-f6x5-jh6r-wrfv (golang.org/x/crypto)

Package: golang.org/x/crypto Affected Versions: Research required Fixed Version: Research required (may already be v0.46.0) Severity: HIGH → MEDIUM (after analysis) CVSS Score: 6.0-7.0

Description: Cryptographic implementation flaws potentially affecting bcrypt, scrypt, or other crypto primitives.

Charon Impact: Used for bcrypt password hashing in user authentication. Critical for security.

Mitigation: Verify CVE applicability, upgrade if needed, test authentication flow.

Research Notes:

  • Scan suggests upgrade from v0.46.0 to v0.45.0 (downgrade) - likely false positive
  • Need to verify if CVEs apply to bcrypt specifically
  • Current v0.46.0 may already contain fixes

CVE-2025-60876 (busybox, busybox-binsh, ssl_client)

Package: busybox (Alpine APK) Affected Versions: 1.37.0-r20 and earlier Fixed Version: Research required (likely 1.37.0-r21+) Severity: MEDIUM CVSS Score: 6.0-6.9

Description: Multiple vulnerabilities in BusyBox utilities affecting shell operations and SSL/TLS client functionality.

Charon Impact:

  • busybox: Provides core Unix utilities in Alpine
  • busybox-binsh: Shell interpreter (used by scripts)
  • ssl_client: SSL/TLS client library (used by curl)

Mitigation: Update Alpine base image or packages via apk upgrade.


CVE-2025-10966 (curl)

Package: curl (Alpine APK) Affected Versions: 8.14.1-r2 and earlier Fixed Version: Research required (likely 8.14.1-r3+) Severity: MEDIUM CVSS Score: 6.0-6.9

Description: HTTP client vulnerability potentially affecting request handling, URL parsing, or certificate validation.

Charon Impact: Used to download GeoLite2 database during container startup (Dockerfile line 305-307).

Mitigation: Update Alpine base image or curl package via apk upgrade.


Appendix B: File Reference Index

Critical Files

File Purpose Changes Required
backend/go.mod Go dependencies Update golang.org/x/crypto version
backend/go.sum Dependency checksums Auto-updated with go.mod
Dockerfile Container build Update Alpine base image (lines 22, 246)
.github/workflows/docker-build.yml CI/CD build pipeline Verify expr-lang check (lines 157-197)

Supporting Files

File Purpose Changes Required
CHANGELOG.md Release notes Document security fixes
SECURITY.md Security policy Update vulnerability disclosure
codecov.yml Coverage config Create if needed for threshold enforcement
.gitignore Git exclusions No changes (already comprehensive)
.dockerignore Docker exclusions No changes (already optimized)

Test Files

File Purpose Verification
backend/internal/services/security_service_test.go bcrypt tests Verify password hashing
backend/internal/models/user_test.go User model tests Verify password operations
backend/internal/crypto/encryption_test.go AES encryption tests Verify crypto still works
backend/internal/crowdsec/console_enroll_test.go Enrollment encryption Verify AES-GCM encryption

Appendix C: Command Reference

Quick Reference Commands

Backend Testing:

cd backend
go test ./...                                    # Run all tests
go test -coverprofile=coverage.out ./...        # With coverage
go tool cover -func=coverage.out                # Show coverage
govulncheck ./...                                # Check vulnerabilities

Frontend Testing:

cd frontend
npm run type-check                               # TypeScript check
npm run lint                                     # ESLint
npm run test:ci                                  # Run tests
npm run coverage                                 # Coverage report

Docker Operations:

docker build --no-cache -t charon:test .        # Build fresh image
docker run -d -p 8080:8080 charon:test          # Start container
docker logs <container-id>                       # View logs
docker exec -it <container-id> sh               # Shell access
docker stop <container-id>                       # Stop container
docker rm <container-id>                         # Remove container

Security Scanning:

trivy image --severity HIGH,CRITICAL charon:test           # Scan image
govulncheck ./...                                          # Go modules
docker sbom charon:test > sbom.json                        # Generate SBOM

Integration Tests:

.github/skills/scripts/skill-runner.sh integration-test-all           # All tests
.github/skills/scripts/skill-runner.sh integration-test-coraza        # WAF only
.github/skills/scripts/skill-runner.sh integration-test-crowdsec      # CrowdSec

Appendix D: Troubleshooting Guide

Issue: Go Module Update Fails

Symptoms:

go: golang.org/x/crypto@v0.45.0: invalid version: module contains a go.mod file, so module path must match major version

Solution:

# Check actual latest version
go list -m -versions golang.org/x/crypto

# Update to latest
go get -u golang.org/x/crypto@latest

# Or specific version
go get golang.org/x/crypto@v0.46.0

Issue: Docker Build Fails - Alpine Package Not Found

Symptoms:

ERROR: unable to select packages:
  busybox-1.37.0-r21:
    breaks: world[busybox=1.37.0-r20]

Solution:

# Update package index in Dockerfile
RUN apk update && \
    apk --no-cache add ... && \
    apk --no-cache upgrade

# Or force specific version
RUN apk --no-cache add busybox=1.37.0-r21

Issue: Integration Tests Fail - CrowdSec Not Starting

Symptoms:

CRIT [crowdsec] Failed to load CrowdSec config

Solution:

# Check CrowdSec logs
docker logs <container-id> | grep crowdsec

# Verify config directory
docker exec <container-id> ls -la /etc/crowdsec

# Check enrollment status
docker exec <container-id> cscli config show

# Re-initialize
docker exec <container-id> cscli config restore

Issue: Coverage Drops Below Threshold

Symptoms:

Codecov: Coverage decreased (-2.5%) to 82.4%

Solution:

# Identify uncovered lines
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | grep -v "100.0%"

# Add tests for uncovered code
# See specific file coverage:
go tool cover -func=coverage.out | grep "security_service.go"

# Generate HTML report for analysis
go tool cover -html=coverage.out -o coverage.html

Issue: Trivy Still Reports Vulnerabilities

Symptoms:

CVE-2025-60876 (busybox): Still detected after rebuild

Solution:

# Verify package versions in running container
docker run --rm charon:test apk info busybox
# If version still old:

# Clear Docker build cache
docker builder prune -af

# Rebuild with no cache
docker build --no-cache --pull -t charon:test .

# Verify Alpine package repos updated
docker run --rm charon:test sh -c "apk update && apk list --upgradable"

Document Control

Version: 1.0 Last Updated: January 11, 2026 Author: Security Team / GitHub Copilot Review Cycle: Update after each phase completion

Changelog:

  • 2026-01-11 v1.0: Initial version created based on security scan findings
  • 2026-01-11 v1.1: MAJOR UPDATE - Added CrowdSec expr-lang patching (Task 3B), corrected vulnerability inventory per Supervisor feedback, downgraded golang.org/x/crypto to MEDIUM (likely false positive), updated timeline to 6-8 hours

Next Review: After Task 3B (CrowdSec patch) implementation, then after full Phase 3 completion.

Related Documents:

  • docs/plans/crowdsec_source_build.md - Complete technical implementation plan for CrowdSec expr-lang patch

END OF DOCUMENT