feat: add nightly branch workflow

This commit is contained in:
GitHub Actions
2026-01-13 22:11:28 +00:00
parent d27c925ba5
commit 4adcd9eda1
187 changed files with 8897 additions and 1614 deletions

View File

@@ -14,38 +14,45 @@ This document tracks security vulnerabilities that have been assessed and accept
**CVSS**: TBD
#### Affected Components
- **busybox**: 1.37.0-r20
- **busybox-binsh**: 1.37.0-r20
- **ssl_client**: 1.37.0-r20
#### Vulnerability Description
CVE-2025-60876 affects multiple busybox utilities in Alpine Linux 3.21. As of 2026-01-11, no patch is available from Alpine Security Team.
#### Risk Assessment
**Exploitability**: Low
- Requires local shell access or specific network conditions
- Not directly exposed through application APIs
- Container isolation limits attack surface
**Impact**: Limited
- busybox provides minimal shell utilities used for healthchecks and diagnostics
- ssl_client used internally by Alpine package manager
- No direct user input processing through these utilities
**Mitigation Strategies**:
1. **Container Isolation**: Running in containerized environment limits local access
2. **Network Policies**: Ingress/egress rules restrict network-based exploitation
3. **Non-Privileged Container**: Runs as non-root user (caddy user)
4. **Read-Only Filesystem**: Application code and binaries mounted read-only where possible
#### Monitoring Plan
- **Frequency**: Daily checks of Alpine Security advisories
- **Source**: https://security.alpinelinux.org/vuln
- **Source**: <https://security.alpinelinux.org/vuln>
- **Alert Trigger**: Patch release for CVE-2025-60876
- **Action**: Rebuild Docker image with updated Alpine base
#### Remediation Timeline
- **Expected Upstream Fix**: TBD (monitoring Alpine Security Team)
- **Automatic Remediation**: Will be included in next Docker rebuild after Alpine patch
- **Review Date**: 2026-02-11 (30 days) or upon patch release, whichever is sooner
@@ -60,37 +67,44 @@ CVE-2025-60876 affects multiple busybox utilities in Alpine Linux 3.21. As of 20
**CVSS**: TBD
#### Affected Components
- **curl**: 8.14.1-r2
- **libcurl**: 8.14.1-r2 (implicit)
#### Vulnerability Description
CVE-2025-10966 affects libcurl in Alpine Linux 3.21. As of 2026-01-11, no patch is available from Alpine Security Team.
#### Risk Assessment
**Exploitability**: Medium
- Requires network access and specific request patterns
- curl used only in healthcheck scripts and manual debugging
- Not exposed directly to user input
**Impact**: Limited
- curl invoked only for internal health monitoring
- No user-controlled URLs passed to curl
- Healthcheck scripts use hardcoded localhost endpoints
**Mitigation Strategies**:
1. **Limited Usage**: curl only used for internal healthchecks (`http://localhost:8080/api/v1/health`)
2. **No User Input**: All curl invocations use hardcoded, internal URLs
3. **Container Isolation**: Network policies restrict external access
4. **Alternative Available**: Application can fall back to TCP socket checks
#### Monitoring Plan
- **Frequency**: Daily checks of Alpine Security advisories
- **Source**: https://security.alpinelinux.org/vuln
- **Source**: <https://security.alpinelinux.org/vuln>
- **Alert Trigger**: Patch release for CVE-2025-10966
- **Action**: Rebuild Docker image with updated Alpine base
#### Remediation Timeline
- **Expected Upstream Fix**: TBD (monitoring Alpine Security Team)
- **Automatic Remediation**: Will be included in next Docker rebuild after Alpine patch
- **Review Date**: 2026-02-11 (30 days) or upon patch release, whichever is sooner
@@ -100,16 +114,19 @@ CVE-2025-10966 affects libcurl in Alpine Linux 3.21. As of 2026-01-11, no patch
## Review Schedule
### Quarterly Security Review
- **Next Review**: 2026-04-11
- **Scope**: Re-assess all accepted risks, evaluate alternative base images
- **Attendees**: Security team, DevOps, Engineering Director
### Monthly Monitoring
- **Frequency**: First Monday of each month
- **Scope**: Check Alpine and upstream security advisories
- **Action**: Update this document if status changes
### Continuous Monitoring
- **Automated**: GitHub Dependabot, Renovate Bot
- **Manual**: Daily check of Alpine security feed during active incident periods
@@ -130,15 +147,18 @@ Accepted risks will be escalated to immediate remediation if:
## Alternative Mitigation Considered
### Switch to Distroless Base Image
**Status**: Under Evaluation
**Timeline**: Q1 2026
**Pros**:
- Minimal attack surface (no shell, no package manager)
- Faster security patches from Google
- Smaller image size
**Cons**:
- Debugging challenges (no shell access)
- May require custom healthcheck mechanisms
- Migration effort required
@@ -154,6 +174,7 @@ Accepted risks will be escalated to immediate remediation if:
**Review Scheduled**: 2026-02-11
**Rationale**: The assessed risk from these Medium-severity Alpine CVEs is acceptable given:
1. Low exploitability in containerized environment
2. No upstream patches available
3. Effective mitigation strategies in place

View File

@@ -5,6 +5,7 @@
Server-Side Request Forgery (SSRF) is a critical web security vulnerability where an attacker can abuse server functionality to access or manipulate internal resources. Charon implements comprehensive defense-in-depth SSRF protection across all features that accept user-controlled URLs.
**Status**: ✅ **CodeQL CWE-918 Resolved** (PR #450)
- Taint chain break verified via static analysis
- Test coverage: 90.2% for URL validation utilities
- Zero security vulnerabilities (Trivy, govulncheck clean)
@@ -91,10 +92,12 @@ Charon validates all user-controlled URLs in the following features:
**Protection**: All webhook URLs are validated before saving to prevent SSRF attacks when security events trigger notifications.
**Validation on**:
- Configuration save (fail-fast)
- Notification delivery (defense-in-depth)
**Example Valid URL**:
```json
{
"webhook_url": "https://hooks.slack.com/services/T00/B00/XXX"
@@ -102,6 +105,7 @@ Charon validates all user-controlled URLs in the following features:
```
**Blocked URLs**:
- Private IPs: `http://192.168.1.1/admin`
- Cloud metadata: `http://169.254.169.254/latest/meta-data/`
- Internal hostnames: `http://internal-db.local:3306/`
@@ -117,6 +121,7 @@ Charon validates all user-controlled URLs in the following features:
**Use Case**: Send notifications to Discord, Slack, or custom monitoring systems.
**Example Valid URL**:
```json
{
"webhook_url": "https://discord.com/api/webhooks/123456/abcdef"
@@ -134,6 +139,7 @@ Charon validates all user-controlled URLs in the following features:
**Admin Access Required**: Yes (prevents abuse by non-privileged users)
**Example Usage**:
```bash
curl -X POST http://localhost:8080/api/v1/settings/test-url \
-H "Content-Type: application/json" \
@@ -150,6 +156,7 @@ curl -X POST http://localhost:8080/api/v1/settings/test-url \
**Protection**: CrowdSec hub URLs are validated against an allowlist of official hub domains. Custom hub URLs require HTTPS.
**Allowed Domains**:
- `hub-data.crowdsec.net` (official hub)
- `raw.githubusercontent.com` (official mirror)
- `*.example.com`, `*.local` (test domains, testing only)
@@ -165,6 +172,7 @@ curl -X POST http://localhost:8080/api/v1/settings/test-url \
**Protection**: GitHub API URLs are validated to ensure only official GitHub domains are queried. Prevents SSRF via update check manipulation.
**Allowed Domains**:
- `api.github.com`
- `github.com`
@@ -187,6 +195,7 @@ Charon blocks **13+ IP ranges** to prevent SSRF attacks:
| `192.168.0.0/16` | Class C private network | `192.168.1.1` |
**Attack Example**:
```bash
# Attacker attempts to access internal database
curl -X POST /api/v1/settings/security/webhook \
@@ -209,6 +218,7 @@ curl -X POST /api/v1/settings/security/webhook \
| `100.100.100.200` | Alibaba Cloud | Instance metadata |
**Attack Example**:
```bash
# Attacker attempts AWS metadata access
curl -X POST /api/v1/settings/security/webhook \
@@ -219,6 +229,7 @@ curl -X POST /api/v1/settings/security/webhook \
```
**Why This Matters**: Cloud metadata endpoints expose:
- IAM role credentials (AWS access keys)
- Service account tokens (GCP)
- Managed identity credentials (Azure)
@@ -236,6 +247,7 @@ curl -X POST /api/v1/settings/security/webhook \
| `::1/128` | IPv6 loopback | `::1` |
**Attack Example**:
```bash
# Attacker attempts to access Charon's internal API
curl -X POST /api/v1/settings/security/webhook \
@@ -277,6 +289,7 @@ Charon uses a **four-stage validation pipeline** for all user-controlled URLs:
### Stage 1: URL Format Validation
**Checks**:
- ✅ URL is not empty
- ✅ URL parses correctly (valid syntax)
- ✅ Scheme is `http` or `https` only
@@ -284,6 +297,7 @@ Charon uses a **four-stage validation pipeline** for all user-controlled URLs:
- ✅ No credentials in URL (e.g., `http://user:pass@example.com`)
**Blocked Schemes**:
- `file://` (file system access)
- `ftp://` (FTP protocol smuggling)
- `gopher://` (legacy protocol exploitation)
@@ -291,6 +305,7 @@ Charon uses a **four-stage validation pipeline** for all user-controlled URLs:
- `javascript:` (XSS/code injection)
**Example Validation Failure**:
```go
// Blocked: Invalid scheme
err := ValidateExternalURL("file:///etc/passwd")
@@ -302,17 +317,20 @@ err := ValidateExternalURL("file:///etc/passwd")
### Stage 2: DNS Resolution
**Checks**:
- ✅ Hostname resolves via DNS (3-second timeout)
- ✅ At least one IP address returned
- ✅ Handles both IPv4 and IPv6 addresses
- ✅ Prevents DNS timeout attacks
**Protection Against**:
- Non-existent domains (typosquatting)
- DNS timeout DoS attacks
- DNS rebinding (resolved IPs checked immediately before request)
**Example**:
```go
// Resolve hostname to IPs
ips, err := net.LookupIP("webhook.example.com")
@@ -331,6 +349,7 @@ for _, ip := range ips {
### Stage 3: IP Range Validation
**Checks**:
- ✅ ALL resolved IPs are checked (not just the first)
- ✅ Private IP ranges blocked (13+ CIDR blocks)
- ✅ IPv4 and IPv6 support
@@ -338,6 +357,7 @@ for _, ip := range ips {
- ✅ Loopback and link-local addresses blocked
**Validation Logic**:
```go
func isPrivateIP(ip net.IP) bool {
// Check loopback and link-local first (fast path)
@@ -376,12 +396,14 @@ func isPrivateIP(ip net.IP) bool {
### Stage 4: Request Execution
**Checks**:
- ✅ Use validated IP explicitly (bypass DNS caching attacks)
- ✅ Set timeout (5-10 seconds, context-based)
- ✅ Limit redirects (0-2 maximum)
- ✅ Log all SSRF attempts with HIGH severity
**HTTP Client Configuration**:
```go
client := &http.Client{
Timeout: 10 * time.Second,
@@ -403,16 +425,19 @@ client := &http.Client{
**Purpose**: Enable local development and integration testing
**When Allowed**:
- URL connectivity testing with `WithAllowLocalhost()` option
- Development environment (`CHARON_ENV=development`)
- Explicit test fixtures in test code
**Allowed Addresses**:
- `localhost` (hostname)
- `127.0.0.1` (IPv4)
- `::1` (IPv6)
**Example**:
```go
// Production: Blocked
err := ValidateExternalURL("http://localhost:8080/admin")
@@ -430,11 +455,13 @@ err := ValidateExternalURL("http://localhost:8080/admin", WithAllowLocalhost())
### When to Use `WithAllowLocalhost`
**✅ Safe Uses**:
1. **Unit tests**: Testing validation logic with mock servers
2. **Integration tests**: Testing against local test fixtures
3. **Development mode**: Local webhooks for debugging (with explicit flag)
**❌ Unsafe Uses**:
1. Production webhook configurations
2. User-facing features without strict access control
3. Any scenario where an attacker controls the URL
@@ -452,6 +479,7 @@ err := ValidateExternalURL("http://localhost:8080/admin", WithAllowLocalhost())
- Container orchestration APIs (Docker, Kubernetes)
2. **Port Scanning**: Attacker can enumerate services:
```bash
# Scan internal ports via error messages
http://localhost:22/ # SSH (connection refused)
@@ -492,6 +520,7 @@ err := ValidateExternalURL("http://localhost:8080/admin", WithAllowLocalhost())
```
**Why These Are Safe**:
- ✅ Use HTTPS (encrypted, authenticated)
- ✅ Resolve to public IP addresses
- ✅ Operated by known, trusted services
@@ -542,6 +571,7 @@ err := ValidateExternalURL("http://localhost:8080/admin", WithAllowLocalhost())
```
**Why These Are Blocked**:
- ❌ Expose internal network resources
- ❌ Allow cloud metadata access (credentials leak)
- ❌ Enable protocol smuggling
@@ -557,11 +587,13 @@ err := ValidateExternalURL("http://localhost:8080/admin", WithAllowLocalhost())
**Attack**: DNS record changes between validation and request execution
**Charon's Defense**:
1. Resolve hostname immediately before HTTP request
2. Check ALL resolved IPs against blocklist
3. Use explicit IP in HTTP client (bypass DNS cache)
**Example Attack Scenario**:
```
Time T0: Attacker configures webhook: http://evil.com/webhook
DNS Resolution: evil.com → 203.0.113.10 (public IP, passes validation)
@@ -577,6 +609,7 @@ Time T3: Security event triggers webhook
```
**Protection Mechanism**:
```go
// Validation happens at configuration save AND request time
func (s *SecurityNotificationService) sendWebhook(ctx context.Context, webhookURL string, event models.SecurityEvent) error {
@@ -602,6 +635,7 @@ func (s *SecurityNotificationService) sendWebhook(ctx context.Context, webhookUR
**Attack**: Race condition between validation and request
**Charon's Defense**:
- Validation and DNS resolution happen in a single transaction
- HTTP request uses resolved IP (no re-resolution)
- Timeout prevents long-running requests that could stall validation
@@ -613,6 +647,7 @@ func (s *SecurityNotificationService) sendWebhook(ctx context.Context, webhookUR
**Attack**: Initial URL is valid, but redirects to private IP
**Charon's Defense**:
```go
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
@@ -637,6 +672,7 @@ client := &http.Client{
**Charon's Approach**: Generic user-facing errors, detailed server logs
**User-Facing Error**:
```json
{
"error": "URL resolves to a private IP address (blocked for security)"
@@ -644,17 +680,20 @@ client := &http.Client{
```
**Server Log**:
```
level=HIGH msg="Blocked SSRF attempt" url="http://192.168.1.100/admin" resolved_ip="192.168.1.100" user_id="admin123" timestamp="2025-12-23T10:30:00Z"
```
**What's Hidden**:
- ❌ Internal IP addresses (except in validation context)
- ❌ Network topology details
- ❌ Service names or ports
- ❌ DNS resolution details
**What's Revealed**:
- ✅ Validation failure reason (security context)
- ✅ User-friendly explanation
- ✅ Security justification
@@ -670,11 +709,13 @@ level=HIGH msg="Blocked SSRF attempt" url="http://192.168.1.100/admin" resolved_
**Cause**: The URL's hostname resolves to a private IP range (RFC 1918, loopback, link-local).
**Solutions**:
1. ✅ Use a publicly accessible webhook endpoint
2. ✅ If webhook must be internal, use a public-facing gateway/proxy
3. ✅ For development, use a service like ngrok or localtunnel
**Example Fix**:
```bash
# BAD: Internal IP
http://192.168.1.100/webhook
@@ -693,11 +734,13 @@ https://abc123.ngrok.io/webhook
**Cause**: The URL uses `localhost`, `127.0.0.1`, or `::1` without the localhost exception enabled.
**Solutions**:
1. ✅ Use a public webhook service (Slack, Discord, etc.)
2. ✅ Deploy webhook receiver on a public server
3. ✅ For testing, use test URL endpoint with admin privileges
**Example Fix**:
```bash
# BAD: Localhost
http://localhost:3000/webhook
@@ -720,6 +763,7 @@ curl -X POST /api/v1/settings/test-url \
**Solution**: Change the URL scheme to `http://` or `https://`.
**Example Fix**:
```bash
# BAD: File protocol
file:///etc/passwd
@@ -735,12 +779,14 @@ https://api.example.com/webhook
**Cause**: Hostname does not resolve, or the server is unreachable.
**Solutions**:
1. ✅ Verify the domain exists and is publicly resolvable
2. ✅ Check for typos in the URL
3. ✅ Ensure the webhook receiver is running and accessible
4. ✅ Test connectivity with `curl` or `ping` from Charon's network
**Example Debugging**:
```bash
# Test DNS resolution
nslookup webhooks.example.com
@@ -810,6 +856,7 @@ EOF
### When to Contact Security Team
**Report SSRF bypasses if you can**:
1. Access private IPs despite validation
2. Retrieve cloud metadata endpoints
3. Use protocol smuggling to bypass scheme checks
@@ -817,6 +864,7 @@ EOF
5. Bypass IP range checks with IPv6 or encoding tricks
**How to Report**:
- Email: `security@charon.example.com` (if configured)
- GitHub Security Advisory: <https://github.com/Wikid82/charon/security/advisories/new>
- Include: steps to reproduce, proof of concept (non-destructive)
@@ -828,11 +876,13 @@ EOF
### How to Use `ValidateExternalURL`
**Import**:
```go
import "github.com/Wikid82/charon/backend/internal/security"
```
**Basic Usage**:
```go
func SaveWebhookConfig(webhookURL string) error {
// Validate before saving to database
@@ -847,6 +897,7 @@ func SaveWebhookConfig(webhookURL string) error {
```
**With Options**:
```go
// Allow HTTP (not recommended for production)
validatedURL, err := security.ValidateExternalURL(webhookURL,
@@ -907,11 +958,13 @@ For runtime HTTP requests where SSRF protection must be enforced at connection t
3. **Layer 3: Redirect Validation** - Each redirect target is validated before following
**Import**:
```go
import "github.com/Wikid82/charon/backend/internal/network"
```
**Basic Usage**:
```go
// Create a safe HTTP client with default options
client := network.NewSafeHTTPClient()
@@ -927,6 +980,7 @@ defer resp.Body.Close()
```
**With Options**:
```go
// Custom timeout (default: 10 seconds)
client := network.NewSafeHTTPClient(
@@ -1255,6 +1309,7 @@ func (s *NotificationService) SendWebhook(ctx context.Context, event SecurityEve
Charon maintains extensive test coverage for all SSRF protection mechanisms:
**URL Validation Tests** (90.2% coverage):
- ✅ Private IP detection (IPv4/IPv6)
- ✅ Cloud metadata endpoint blocking (169.254.169.254)
- ✅ DNS resolution with timeout handling
@@ -1263,6 +1318,7 @@ Charon maintains extensive test coverage for all SSRF protection mechanisms:
- ✅ Multiple IP address validation (all must pass)
**Security Notification Tests**:
- ✅ Webhook URL validation on save
- ✅ Webhook URL re-validation on send
- ✅ HTTPS enforcement in production
@@ -1270,12 +1326,14 @@ Charon maintains extensive test coverage for all SSRF protection mechanisms:
- ✅ DNS rebinding protection
**Integration Tests**:
- ✅ End-to-end webhook delivery with SSRF checks
- ✅ CrowdSec hub URL validation
- ✅ URL connectivity testing with admin-only access
- ✅ Performance benchmarks (< 10ms validation overhead)
**Test Pattern Example**:
```go
func TestValidateExternalURL_CloudMetadataDetection(t *testing.T) {
// Test blocking AWS metadata endpoint
@@ -1325,6 +1383,7 @@ We're interested in:
### How to Report
**Preferred Method**: GitHub Security Advisory
1. Go to <https://github.com/Wikid82/charon/security/advisories/new>
2. Provide:
- Steps to reproduce
@@ -1334,6 +1393,7 @@ We're interested in:
3. We'll respond within 48 hours
**Alternative Method**: Email
- Send to: `security@charon.example.com` (if configured)
- Encrypt with PGP key (if available in SECURITY.md)
- Include same information as GitHub advisory
@@ -1341,11 +1401,13 @@ We're interested in:
### Responsible Disclosure
**Please**:
- ✅ Give us time to fix before public disclosure (90 days)
- ✅ Provide clear reproduction steps
- ✅ Avoid destructive testing (don't attack real infrastructure)
**We'll**:
- ✅ Acknowledge your report within 48 hours
- ✅ Provide regular status updates
- ✅ Credit you in release notes (if desired)

View File

@@ -11,10 +11,12 @@
After implementing `--no-cache` builds, the supply chain scan still reports **8 Medium vulnerabilities**. Investigation reveals these are **actual runtime dependencies**, not false positives from cached layers.
**Vulnerability Breakdown**:
- **3 Alpine APK packages** (busybox, curl, ssl_client) - CVE-2025-60876, CVE-2025-10966 (no fixes available)
- **2 Go dependencies** (golang.org/x/crypto v0.42.0) - GHSA-j5w8-q4qc-rx2x, GHSA-f6x5-jh6r-wrfv (fix available: v0.45.0)
**Current Status**:
- ✅ No-cache builds implemented successfully
- ⚠️ Alpine base image vulnerabilities have no upstream patches yet
- 🔧 golang.org/x/crypto requires dependency update
@@ -26,6 +28,7 @@ After implementing `--no-cache` builds, the supply chain scan still reports **8
### Actual Vulnerabilities Found (Not False Positives)
#### 1. Alpine Base Image - busybox (CVE-2025-60876)
**Affected Packages**: busybox, busybox-binsh, ssl_client
**Current Version**: 1.37.0-r20
**Fixed Version**: None available
@@ -34,6 +37,7 @@ After implementing `--no-cache` builds, the supply chain scan still reports **8
**Details**: CVE-2025-60876 affects busybox utilities in Alpine 3.21. No patch is available yet from Alpine upstream.
**Impact**:
- Affects base image utilities (not directly used by application)
- Busybox provides minimal shell and utilities in Alpine
- Low exploitability in containerized environment
@@ -41,6 +45,7 @@ After implementing `--no-cache` builds, the supply chain scan still reports **8
**Recommendation**: Monitor Alpine security advisories for patch release.
#### 2. Alpine Base Image - curl (CVE-2025-10966)
**Current Version**: 8.14.1-r2
**Fixed Version**: None available
**Severity**: Medium
@@ -48,6 +53,7 @@ After implementing `--no-cache` builds, the supply chain scan still reports **8
**Details**: CVE-2025-10966 affects libcurl in Alpine 3.21. No patch is available yet from Alpine upstream.
**Impact**:
- curl is used by healthcheck scripts
- Medium severity with limited attack surface
- Requires network access to exploit
@@ -55,15 +61,18 @@ After implementing `--no-cache` builds, the supply chain scan still reports **8
**Recommendation**: Monitor Alpine security advisories for patch release.
#### 3. Go Dependencies - golang.org/x/crypto (GHSA-j5w8-q4qc-rx2x, GHSA-f6x5-jh6r-wrfv)
**Current Version**: v0.42.0 (transitive dependency)
**Fixed Version**: v0.45.0
**Severity**: Medium
**Details**: Two GitHub Security Advisories affecting golang.org/x/crypto v0.42.0:
- GHSA-j5w8-q4qc-rx2x: SSH connection handling vulnerability
- GHSA-f6x5-jh6r-wrfv: SSH key parsing vulnerability
**Dependency Chain**:
```
github.com/go-playground/validator/v10@v10.28.0
└─> golang.org/x/crypto@v0.42.0 (VULNERABLE)
@@ -72,6 +81,7 @@ Direct dependency: golang.org/x/crypto@v0.46.0 (SAFE)
```
**Impact**:
- Transitive dependency from go-playground/validator
- validator library used for input validation in API handlers
- Medium severity - requires specific conditions to exploit
@@ -124,6 +134,7 @@ require (
**Expected Impact**: Eliminates 2-4 of the 8 Medium vulnerabilities (the golang.org/x/crypto issues).
**Testing Required**:
- ✅ Backend unit tests
- ✅ Integration tests
- ✅ Validate validator/v10 compatibility
@@ -144,25 +155,31 @@ Since Alpine has not released patches for CVE-2025-60876 and CVE-2025-10966:
#### 3. Monitor Alpine Security Advisories
**Action Plan**:
1. Subscribe to Alpine Linux security mailing list
2. Check https://security.alpinelinux.org/vuln daily
2. Check <https://security.alpinelinux.org/vuln> daily
3. When patches are released:
```bash
# Update Dockerfile base image
FROM caddy:2-alpine # This will pull the latest Alpine patch
```
4. Rebuild and re-scan to verify resolution
#### 4. Monitor go-playground/validator Updates
**Action Plan**:
1. Check https://github.com/go-playground/validator/releases weekly
1. Check <https://github.com/go-playground/validator/releases> weekly
2. When validator releases version with golang.org/x/crypto@v0.45.0+:
```bash
cd backend
go get -u github.com/go-playground/validator/v10@latest
go mod tidy
```
3. Remove the replace directive from go.mod
4. Re-run tests and supply chain scan
@@ -173,11 +190,13 @@ Since Alpine has not released patches for CVE-2025-60876 and CVE-2025-10966:
#### 5. Implement Automated Dependency Updates
**Tools to Consider**:
- Renovate Bot (already configured) - increase update frequency
- Dependabot for Go modules
- Automated security patch PRs
**Configuration**:
```json
// .github/renovate.json
{
@@ -195,11 +214,13 @@ Since Alpine has not released patches for CVE-2025-60876 and CVE-2025-10966:
#### 6. Alternative Base Images
**Research Options**:
1. **Distroless** (Google) - Minimal attack surface, no shell
2. **Alpine with chainguard** - Hardened Alpine with faster security patches
3. **Wolfi** (Chainguard) - Modern, security-first distribution
**Evaluation Criteria**:
- Security patch velocity
- Compatibility with Caddy
- Image size impact
@@ -285,11 +306,13 @@ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
### Expected Results
**Before Replace Directive**:
```
Medium: 8 (busybox x3, curl x1, golang.org/x/crypto x4)
```
**After Replace Directive**:
```
Medium: 4 (busybox x3, curl x1)
```
@@ -349,6 +372,7 @@ go test ./...
Implementing `--no-cache` builds across all workflows eliminates false positive vulnerability reports from cached Go module layers. This provides accurate security posture reporting, clean SBOMs, and compliance-ready artifacts. The trade-off of slightly longer build times is acceptable for the security benefits gained.
**Next Steps**:
1. ✅ Changes committed to `docker-build.yml` and `waf-integration.yml`
2. ⏳ Wait for next PR build to validate clean scan results
3. ⏳ Monitor build time impact and adjust if needed
@@ -384,12 +408,14 @@ Implementing `--no-cache` builds across all workflows eliminates false positive
### Risk Assessment
**Alpine CVEs (3 unique vulnerabilities in 4 packages)**:
- **Exploitability**: Low (requires local access or specific network conditions)
- **Impact**: Limited (utilities not directly exposed to user input)
- **Mitigation**: Containerization limits attack surface
- **Status**: **ACCEPTED RISK** - Monitor for upstream patches
**golang.org/x/crypto (2 unique vulnerabilities, 4 entries due to scan reporting)**:
- **Exploitability**: Medium (requires SSH connection handling)
- **Impact**: Medium (transitive dependency from validator)
- **Mitigation**: Add replace directive to force v0.45.0