# 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:**

```go
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:**

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

2. **Update go.mod (if upgrade needed):**

   ```bash
   cd backend
   go get -u golang.org/x/crypto@latest
   go mod tidy
   ```

3. **Run backend tests:**

   ```bash
   cd backend
   go test ./... -v
   ```

4. **Coverage check:**

   ```bash
   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:

```dockerfile
# 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:**

   ```bash
   grep -A1 "expr-lang/expr" Dockerfile
   ```

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

2. **Rebuild Docker image:**

   ```bash
   docker build --no-cache -t charon:vuln-test .
   ```

3. **Extract Caddy binary and verify:**

   ```bash
   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:**

   ```bash
   # 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):**

```dockerfile
# 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):**

```dockerfile
# 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:**

   ```bash
   docker build --no-cache -t charon:crowdsec-patch .
   ```

2. **Extract cscli binary:**

   ```bash
   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:**

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

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

4. **Run CrowdSec integration tests:**

   ```bash
   .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:**

```dockerfile
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:**

```dockerfile
# 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)

```dockerfile
# OLD
ARG CADDY_IMAGE=alpine:3.23

# NEW
ARG CADDY_IMAGE=alpine:3.24
```

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

```dockerfile
# OLD
FROM alpine:3.23 AS crowdsec-fallback

# NEW
FROM alpine:3.24 AS crowdsec-fallback
```

**Change 3:** Update final runtime base (line 284)

```dockerfile
# OLD
FROM ${CADDY_IMAGE}

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

**Change 4:** Update Renovate tracking comments

```dockerfile
# 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**

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

**Step 2: Verify package versions**

```bash
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**

```bash
# 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**

```bash
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**

```bash
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):**

```bash
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:**

```bash
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:**

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

   Expected: All pass, coverage ≥85%

2. **Frontend Tests:**

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

   Expected: All pass, coverage report generated

3. **Docker Build:**

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

   Expected: Build succeeds, container starts

4. **Integration Tests:**

   ```bash
   .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:**

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

   Expected: Zero HIGH/CRITICAL vulnerabilities

### 3.3 Security Scan Re-run

**Step 1: Trivy Image Scan**

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

**Step 2: govulncheck (Go modules)**

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

**Step 3: Compare Results**

```bash
# 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**

```bash
.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:**

```bash
# 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`

```yaml
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:

   ```dockerfile
   # 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:

   ```dockerfile
   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**

```bash
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)**

```bash
# 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**

```bash
# 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:**

```bash
# 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:**

```bash
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:

   ```dockerfile
   # 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:**

```bash
# 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:**

- [x] Dockerfile contains v1.17.7 reference
- [x] 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`:

```dockerfile
# 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)**

```dockerfile
# 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:

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

**Commands:**

```bash
# 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:**

```bash
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**

```diff
# 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:**

```bash
# 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:**

```bash
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:**

```bash
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:**

```json
// 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:**

```bash
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:**

```json
// 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:**

```bash
# 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:**

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

**Build Verification:**

```bash
# 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)

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

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

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

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

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

```bash
# 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:**

```json
// 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

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

**VS Code Task:**

```json
// 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

```bash
# 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:**

- golang.org/x/crypto@v0.46.0 (or later, if upgraded)
- github.com/expr-lang/expr@v1.17.7 (in Caddy binary)
- Alpine 3.23 (or 3.24) base packages with security patches

#### 9.4 CodeQL Scan (Optional - runs in CI)

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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:**

```bash
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:**

```bash
# 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:**

```bash
# 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:**

   ```bash
   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:**

   ```markdown
   ## [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:**

```bash
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:**

```bash
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:**

```bash
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:**

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

**Integration Tests:**

```bash
.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:**

```bash
# 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:**

```bash
# 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:**

```bash
# 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:**

```bash
# 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:**

```bash
# 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**
