Files
Charon/docs/plans/current_spec.md

10 KiB

Issue #365: Additional Security Enhancements - Implementation Specification

Status: Planning Complete Created: 2025-12-21 Issue: https://github.com/Wikid82/Charon/issues/365 Branch: feature/issue-365-additional-security PRs: #436 (targets development), #437 (targets main)


Executive Summary

This specification details the implementation plan for Issue #365, which addresses six security enhancement areas. After thorough codebase analysis, this document provides file-by-file implementation details, phase breakdown, and complexity estimates.

Scope Summary

Requirement Status Complexity Phase
Supply Chain - SBOM Generation TODO Medium 2
DNS Hijacking - Documentation TODO Low 1
TLS Downgrade - Documentation Partial Low 1
Privilege Escalation - Container Hardening ⚠️ Partial Medium 2
Session Hijacking - Cookie/CSP Audit Implemented Low 1
Timing Attacks - Constant-Time Comparison TODO Medium 2
SIRP Documentation TODO Low 1
Security Update Notifications Doc TODO Low 1

Codebase Research Findings

1. Cookie/Session Implementation

Location: backend/internal/api/handlers/auth_handler.go

Current Implementation (lines 52-73):

func setSecureCookie(c *gin.Context, name, value string, maxAge int) {
    scheme := requestScheme(c)
    secure := isProduction() && scheme == "https"
    sameSite := http.SameSiteStrictMode
    if scheme != "https" {
        sameSite = http.SameSiteLaxMode
    }
    c.SetSameSite(sameSite)
    c.SetCookie(name, value, maxAge, "/", "", secure, true) // HttpOnly: true ✅
}

Assessment: SECURE - All cookie security attributes properly configured:

  • HttpOnly: true - Prevents XSS access
  • Secure: true (production + HTTPS)
  • SameSite: Strict (HTTPS) / Lax (HTTP dev)

2. Security Headers Implementation

Location: backend/internal/api/middleware/security.go

Current Headers Set:

  • Content-Security-Policy (CSP)
  • Strict-Transport-Security (HSTS) with preload
  • X-Frame-Options: DENY
  • X-Content-Type-Options: nosniff
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy (restricts camera, mic, etc.)
  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Resource-Policy: same-origin

Assessment: COMPREHENSIVE - All major security headers present.

3. Token Comparison Methods

Locations Analyzed:

File Function Method Status
models/user.go#L62 CheckPassword bcrypt.CompareHashAndPassword Constant-time
services/security_service.go#L151 VerifyBreakGlassToken bcrypt.CompareHashAndPassword Constant-time
services/auth_service.go#L128 ValidateToken JWT library Handled by library

Potential Issue Found: Invite token validation uses database lookup which could leak timing:

  • Location: backend/internal/api/handlers/user_handler.go (AcceptInvite)
  • Risk: Low (requires network timing analysis)
  • Recommendation: Add constant-time wrapper for token comparison after DB lookup

4. Current Security Documentation

Location: docs/security.md

Current Coverage:

  • Cerberus security suite (CrowdSec, WAF, ACL)
  • Access Lists configuration
  • Certificate management
  • Break-glass token
  • Zero-day protection explanation
  • TLS version enforcement (not documented)
  • DNS security (not documented)
  • SIRP (not documented)
  • Container hardening (not documented)

5. CI/CD Pipeline Analysis

Location: .github/workflows/docker-build.yml

Current State:

  • Trivy vulnerability scanning (SARIF + table output)
  • Weekly security rebuilds (separate workflow)
  • Caddy security patches verification
  • SBOM generation (not implemented)
  • SBOM attestation (not implemented)

Best Integration Point: After build-and-push step, before Trivy scan (around line 130)

6. Dockerfile Security Analysis

Location: Dockerfile

Current Security Features:

  • Non-root user (charon:charon, UID 1000)
  • Healthcheck configured
  • Minimal base image (Alpine)
  • Multi-stage build (reduces attack surface)
  • ⚠️ Root filesystem writable (can be improved)
  • ⚠️ All capabilities retained (can drop unnecessary ones)

Phase 1: Documentation Enhancements (Estimated: 1-2 hours)

1.1 TLS Downgrade Attack Documentation

File: docs/security.md

Add Section:

## TLS Security

### TLS Version Enforcement

Charon (via Caddy) enforces a minimum TLS version of 1.2 by default. This prevents TLS downgrade attacks that attempt to force connections to use vulnerable TLS 1.0 or 1.1.

**What's Protected:**
- ✅ TLS 1.0/1.1 downgrade attacks
- ✅ BEAST, POODLE, and similar protocol-level attacks
- ✅ Weak cipher suite negotiation

**HSTS (HTTP Strict Transport Security):**
Charon sets HSTS headers with:
- `max-age=31536000` (1 year)
- `includeSubDomains`
- `preload` (for browser preload lists)

Complexity: Low | Dependencies: None


1.2 DNS Hijacking Documentation

File: docs/security.md

Add Section:

## DNS Security

### Protecting Against DNS Hijacking

Configure your upstream resolver to use DNS-over-HTTPS (DoH) or DNS-over-TLS (DoT):

**Docker Host Configuration:**
```bash
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com
DNSOverTLS=yes

Additional Protections:

  1. DNSSEC: Ensure your domain registrar supports DNSSEC
  2. CAA Records: Restrict which CAs can issue certs for your domain

**Complexity**: Low | **Dependencies**: None

---

### 1.3 Security Incident Response Plan

**New File**: `docs/security-incident-response.md`

**Content**: Incident classification, detection, containment, recovery procedures

**Complexity**: Low | **Dependencies**: None

---

### 1.4 Security Update Notifications

**Files**: `docs/getting-started.md`, `docs/security.md`

**Add**: GitHub Watch instructions, Watchtower/Diun configuration examples

**Complexity**: Low | **Dependencies**: None

---

## Phase 2: Code Changes (Estimated: 4-6 hours)

### 2.1 SBOM Generation

**File**: `.github/workflows/docker-build.yml`

**Changes** (add after build-and-push step):
```yaml
- name: Generate SBOM (CycloneDX)
  uses: anchore/sbom-action@v0
  with:
    image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build-and-push.outputs.digest }}
    format: cyclonedx-json
    output-file: sbom.cyclonedx.json

- name: Attest SBOM to Image
  if: github.event_name != 'pull_request'
  uses: actions/attest-sbom@v2
  with:
    subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
    subject-digest: ${{ steps.build-and-push.outputs.digest }}
    sbom-path: sbom.cyclonedx.json

Additional Files:

  • .gitignore: Add sbom*.json
  • .dockerignore: Add sbom*.json

Complexity: Medium | Dependencies: None


2.2 Container Hardening Documentation

File: docs/security.md

Add Example:

services:
  charon:
    image: ghcr.io/wikid82/charon:latest
    read_only: true
    tmpfs:
      - /tmp:size=100M
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true

Complexity: Medium | Dependencies: Testing with read-only FS


2.3 Constant-Time Token Comparison

New File: backend/internal/util/crypto.go

package util

import "crypto/subtle"

// ConstantTimeCompare compares two strings in constant time.
func ConstantTimeCompare(a, b string) bool {
    return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}

New Test File: backend/internal/util/crypto_test.go

Modify: backend/internal/api/handlers/user_handler.go - Use constant-time comparison in AcceptInvite

Complexity: Medium | Dependencies: None


Phase 3: Testing & Validation (Estimated: 2-3 hours)

Required Tests

File Purpose
backend/internal/util/crypto_test.go Constant-time comparison tests + benchmarks
Integration test additions Security header verification

Coverage Requirements

  • All new code must achieve 85% coverage
  • Run: scripts/go-test-coverage.sh

File Change Summary

Files to Create

File Purpose
backend/internal/util/crypto.go Constant-time comparison utilities
backend/internal/util/crypto_test.go Tests for crypto utilities
docs/security-incident-response.md SIRP documentation

Files to Modify

File Changes
docs/security.md TLS, DNS, container hardening sections
docs/getting-started.md Security update notification section
.github/workflows/docker-build.yml SBOM generation steps
.gitignore Add sbom*.json
.dockerignore Add sbom*.json
backend/internal/api/handlers/user_handler.go Constant-time token comparison

Files Verified Secure (No Changes)

File Reason
backend/internal/api/handlers/auth_handler.go Cookie security correct
backend/internal/api/middleware/security.go Headers comprehensive
backend/internal/models/user.go bcrypt is constant-time
backend/internal/services/security_service.go bcrypt is constant-time
Dockerfile Non-root user configured

Out of Scope (Future Issues)

Per Issue #365:

  • Certificate Transparency Log Monitoring
  • MFA via Authentik
  • SSO for Charon admin
  • Audit logging for GDPR/SOC2

Acceptance Criteria

  • Documentation sections added to docs/security.md
  • SIRP document created
  • SBOM generation in CI (CycloneDX format)
  • Constant-time utility with tests
  • Container hardening documented
  • 85%+ test coverage
  • Pre-commit hooks pass

Analysis Date: 2025-12-21 Analyzed By: GitHub Copilot Status: Ready for Implementation