chore: Update current spec to outline Caddy 2.11.1 compatibility, security, and UX impact plan
This commit is contained in:
@@ -1,194 +1,523 @@
|
||||
---
|
||||
post_title: "Current Spec: Resolve Proxy Host Hostname Validation Test Failures"
|
||||
post_title: "Current Spec: Caddy 2.11.1 Compatibility, Security, and UX Impact Plan"
|
||||
categories:
|
||||
- actions
|
||||
- testing
|
||||
- security
|
||||
- backend
|
||||
- frontend
|
||||
- infrastructure
|
||||
tags:
|
||||
- go
|
||||
- proxyhost
|
||||
- unit-tests
|
||||
- validation
|
||||
summary: "Focused plan to resolve failing TestProxyHostService_ValidateHostname malformed URL cases by aligning test expectations with intended validation behavior and validating via targeted service tests and coverage gate."
|
||||
post_date: 2026-02-22
|
||||
- caddy
|
||||
- xcaddy
|
||||
- dependency-management
|
||||
- vulnerability-management
|
||||
- release-planning
|
||||
summary: "Comprehensive, phased plan to evaluate and safely adopt Caddy v2.11.1 in Charon, covering plugin compatibility, CVE impact, xcaddy patch retirement decisions, UI/UX exposure opportunities, and PR slicing strategy with strict validation gates."
|
||||
post_date: 2026-02-23
|
||||
---
|
||||
|
||||
## Active Plan: Resolve Failing Hostname Validation Tests
|
||||
## Active Plan: Caddy 2.11.1 Deep Compatibility and Security Rollout
|
||||
|
||||
Date: 2026-02-22
|
||||
Date: 2026-02-23
|
||||
Status: Active and authoritative
|
||||
Scope Type: Backend test-failure remediation (service validation drift analysis)
|
||||
Scope Type: Architecture/security/dependency research and implementation planning
|
||||
Authority: This is the only active authoritative plan section in this file.
|
||||
|
||||
## Introduction
|
||||
|
||||
This plan resolves backend run failures in `TestProxyHostService_ValidateHostname`
|
||||
for malformed URL cases while preserving intended hostname validation behavior.
|
||||
Charon’s control plane and data plane rely on Caddy as a core runtime backbone.
|
||||
Because Caddy is embedded and rebuilt via `xcaddy`, upgrading from
|
||||
`2.11.0-beta.2` to `2.11.1` is not a routine version bump: it impacts
|
||||
runtime behavior, plugin compatibility, vulnerability posture, and potential UX
|
||||
surface area.
|
||||
|
||||
Primary objective:
|
||||
This plan defines a low-risk, high-observability rollout strategy that answers:
|
||||
|
||||
- Restore green test execution in `backend/internal/services` with a minimal,
|
||||
low-risk change path.
|
||||
1. Which Caddy 2.11.x features should be exposed in Charon UI/API?
|
||||
2. Which existing Charon workarounds became redundant upstream?
|
||||
3. Which `xcaddy` dependency patches remain necessary vs removable?
|
||||
4. Which known vulnerabilities are fixed now and which should remain on watch?
|
||||
|
||||
## Research Findings
|
||||
|
||||
### Evidence Collected
|
||||
### External release and security findings
|
||||
|
||||
- Failing command output confirms two failing subtests:
|
||||
- `TestProxyHostService_ValidateHostname/malformed_https_URL`
|
||||
- `TestProxyHostService_ValidateHostname/malformed_http_URL`
|
||||
- Failure message for both cases: `invalid hostname format`.
|
||||
1. Official release statement confirms `v2.11.1` has no runtime code delta from
|
||||
`v2.11.0` except CI/release process correction. Practical implication:
|
||||
compatibility/security validation should target **2.11.x** behavior, not
|
||||
2.11.1-specific runtime changes.
|
||||
2. Caddy release lists six security patches (mapped to GitHub advisories):
|
||||
- `CVE-2026-27590` → `GHSA-5r3v-vc8m-m96g` (FastCGI split_path confusion)
|
||||
- `CVE-2026-27589` → `GHSA-879p-475x-rqh2` (admin API cross-origin no-cors)
|
||||
- `CVE-2026-27588` → `GHSA-x76f-jf84-rqj8` (host matcher case bypass)
|
||||
- `CVE-2026-27587` → `GHSA-g7pc-pc7g-h8jh` (path matcher escaped-case bypass)
|
||||
- `CVE-2026-27586` → `GHSA-hffm-g8v7-wrv7` (mTLS client-auth fail-open)
|
||||
- `CVE-2026-27585` → `GHSA-4xrr-hq4w-6vf4` (glob sanitization bypass)
|
||||
3. NVD/CVE.org entries are currently reserved/not fully enriched. GitHub
|
||||
advisories are the most actionable source right now.
|
||||
|
||||
### Exact Files Involved
|
||||
### Charon architecture and integration findings
|
||||
|
||||
1. `backend/internal/services/proxyhost_service_validation_test.go`
|
||||
- Test function: `TestProxyHostService_ValidateHostname`
|
||||
- Failing cases currently expect `wantErr: false` for malformed URLs.
|
||||
2. `backend/internal/services/proxyhost_service.go`
|
||||
- Service function: `ValidateHostname(host string) error`
|
||||
- Behavior: strips scheme, then validates hostname characters; malformed
|
||||
residual values containing `:` are rejected with `invalid hostname format`.
|
||||
1. Charon compiles custom Caddy in `Dockerfile` via `xcaddy` and injects:
|
||||
- `github.com/greenpau/caddy-security`
|
||||
- `github.com/corazawaf/coraza-caddy/v2`
|
||||
- `github.com/hslatman/caddy-crowdsec-bouncer@v0.10.0`
|
||||
- `github.com/zhangjiayin/caddy-geoip2`
|
||||
- `github.com/mholt/caddy-ratelimit`
|
||||
2. Charon applies explicit post-generation `go get` patching in `Dockerfile` for:
|
||||
- `github.com/expr-lang/expr@v1.17.7`
|
||||
- `github.com/hslatman/ipstore@v0.4.0`
|
||||
- `github.com/slackhq/nebula@v1.9.7` (with comment indicating temporary pin)
|
||||
3. Charon CI has explicit dependency inspection gate in
|
||||
`.github/workflows/docker-build.yml` to verify patched `expr-lang/expr`
|
||||
versions in built binaries.
|
||||
|
||||
### Root Cause Determination
|
||||
### Plugin compatibility findings (highest risk area)
|
||||
|
||||
- Root cause is **test expectation drift**, not runtime service regression.
|
||||
- `git blame` shows malformed URL test cases were added on 2026-02-22 with
|
||||
permissive expectations, while validation behavior rejecting malformed host
|
||||
strings predates those additions.
|
||||
- Existing behavior aligns with stricter hostname validation and should remain
|
||||
the default unless product requirements explicitly demand permissive handling
|
||||
of malformed host inputs.
|
||||
Current plugin module declarations (upstream `go.mod`) target older Caddy cores:
|
||||
|
||||
### Confidence Assessment
|
||||
- `greenpau/caddy-security`: `caddy/v2 v2.10.2`
|
||||
- `hslatman/caddy-crowdsec-bouncer`: `caddy/v2 v2.10.2`
|
||||
- `corazawaf/coraza-caddy/v2`: `caddy/v2 v2.9.1`
|
||||
- `zhangjiayin/caddy-geoip2`: `caddy/v2 v2.10.0`
|
||||
- `mholt/caddy-ratelimit`: `caddy/v2 v2.8.0`
|
||||
|
||||
- Confidence score: **95% (High)**
|
||||
- Rationale: direct reproduction, targeted file inspection, and blame history
|
||||
converge on expectation drift.
|
||||
Implication: compile success against 2.11.1 is plausible but not guaranteed.
|
||||
The plan must include matrix build/provision tests before merge.
|
||||
|
||||
### Charon UX and config-surface findings
|
||||
|
||||
Current Caddy-related UI/API exposure is narrow:
|
||||
|
||||
- `frontend/src/pages/SystemSettings.tsx`
|
||||
- state: `caddyAdminAPI`, `sslProvider`
|
||||
- saves keys: `caddy.admin_api`, `caddy.ssl_provider`
|
||||
- `frontend/src/pages/ImportCaddy.tsx` and import components:
|
||||
- Caddyfile parsing/import workflow, not runtime feature toggles
|
||||
- `frontend/src/api/import.ts`, `frontend/src/api/settings.ts`
|
||||
- Backend routes and handlers:
|
||||
- `backend/internal/api/routes/routes.go`
|
||||
- `backend/internal/api/handlers/settings_handler.go`
|
||||
- `backend/internal/api/handlers/import_handler.go`
|
||||
- `backend/internal/caddy/manager.go`
|
||||
- `backend/internal/caddy/config.go`
|
||||
- `backend/internal/caddy/types.go`
|
||||
|
||||
No UI controls currently exist for new Caddy 2.11.x capabilities such as
|
||||
`keepalive_idle`, `keepalive_count`, `trusted_proxies_unix`,
|
||||
`renewal_window_ratio`, or `0-RTT` behavior.
|
||||
|
||||
## Requirements (EARS)
|
||||
|
||||
- WHEN malformed `http://` or `https://` host strings are passed to
|
||||
`ValidateHostname`, THE SYSTEM SHALL return a validation error.
|
||||
- WHEN service validation behavior is intentionally strict, THE TESTS SHALL
|
||||
assert rejection for malformed URL residual host strings.
|
||||
- IF product intent is permissive for malformed inputs, THEN THE SYSTEM SHALL
|
||||
minimally relax parsing logic without weakening valid invalid-character checks.
|
||||
- WHEN changes are completed, THE SYSTEM SHALL pass targeted service tests and
|
||||
the backend coverage gate script.
|
||||
1. WHEN evaluating Caddy `v2.11.1`, THE SYSTEM SHALL validate compatibility
|
||||
against all currently enabled `xcaddy` plugins before changing production
|
||||
defaults.
|
||||
2. WHEN security advisories in Caddy 2.11.x affect modules Charon may use,
|
||||
THE SYSTEM SHALL document exploitability for Charon’s deployment model and
|
||||
prioritize remediation accordingly.
|
||||
3. WHEN an `xcaddy` patch/workaround no longer provides value,
|
||||
THE SYSTEM SHALL remove it only after reproducible build and runtime
|
||||
validation gates pass.
|
||||
4. IF a Caddy 2.11.x feature maps to an existing Charon concept,
|
||||
THEN THE SYSTEM SHALL prefer extending existing UI/components over adding new
|
||||
parallel controls.
|
||||
5. WHEN no direct UX value exists, THE SYSTEM SHALL avoid adding UI for upstream
|
||||
options and keep behavior backend-managed.
|
||||
6. WHEN this rollout completes, THE SYSTEM SHALL provide explicit upstream watch
|
||||
criteria for unresolved/reserved CVEs and plugin dependency lag.
|
||||
|
||||
## Technical Specification
|
||||
## Technical Specifications
|
||||
|
||||
### Minimal Fix Path (Preferred)
|
||||
### Compatibility scope map (code touch inventory)
|
||||
|
||||
Preferred path: **test-only correction**.
|
||||
#### Build/packaging
|
||||
|
||||
1. Update malformed URL table entries in
|
||||
`backend/internal/services/proxyhost_service_validation_test.go`:
|
||||
- `malformed https URL` -> `wantErr: true`
|
||||
- `malformed http URL` -> `wantErr: true`
|
||||
2. Keep current service behavior in
|
||||
`backend/internal/services/proxyhost_service.go` unchanged.
|
||||
3. Optional test hardening (still test-only): assert error contains
|
||||
`invalid hostname format` for those two cases.
|
||||
- `Dockerfile`
|
||||
- `ARG CADDY_VERSION`
|
||||
- `ARG XCADDY_VERSION`
|
||||
- `caddy-builder` stage (`xcaddy build`, plugin list, `go get` patches)
|
||||
- `.github/workflows/docker-build.yml`
|
||||
- binary dependency checks (`go version -m` extraction/gates)
|
||||
- `.github/renovate.json`
|
||||
- regex managers tracking `Dockerfile` patch dependencies
|
||||
|
||||
### Alternative Path (Only if Product Intent Differs)
|
||||
#### Caddy runtime config generation
|
||||
|
||||
Use only if maintainers explicitly confirm malformed URL inputs should pass:
|
||||
- `backend/internal/caddy/manager.go`
|
||||
- `NewManager(...)`
|
||||
- `ApplyConfig(ctx)`
|
||||
- `backend/internal/caddy/config.go`
|
||||
- `GenerateConfig(...)`
|
||||
- `backend/internal/caddy/types.go`
|
||||
- JSON struct model for Caddy config (`Server`, `TrustedProxies`, etc.)
|
||||
|
||||
1. Apply minimal service correction in `ValidateHostname` to normalize malformed
|
||||
scheme inputs before character validation.
|
||||
2. Add or update tests to preserve strict rejection for truly invalid hostnames
|
||||
(e.g., `$`, `@`, `%`, `&`) so validation is not broadly weakened.
|
||||
#### Settings and admin surface
|
||||
|
||||
Decision default for this plan: **Preferred path (test updates only)**.
|
||||
- `backend/internal/api/handlers/settings_handler.go`
|
||||
- `UpdateSetting(...)`, `PatchConfig(...)`
|
||||
- `backend/internal/api/routes/routes.go`
|
||||
- Caddy manager wiring + settings routes
|
||||
- `frontend/src/pages/SystemSettings.tsx`
|
||||
- current Caddy-related controls
|
||||
|
||||
#### Caddyfile import behavior
|
||||
|
||||
- `backend/internal/api/handlers/import_handler.go`
|
||||
- `RegisterRoutes(...)`, `Upload(...)`, `GetPreview(...)`
|
||||
- `backend/internal/caddy/importer.go`
|
||||
- `NormalizeCaddyfile(...)`, `ParseCaddyfile(...)`, `ExtractHosts(...)`
|
||||
- `frontend/src/pages/ImportCaddy.tsx`
|
||||
- import UX and warning handling
|
||||
|
||||
### Feature impact assessment (2.11.x)
|
||||
|
||||
#### Candidate features for potential Charon exposure
|
||||
|
||||
1. Keepalive server options (`keepalive_idle`, `keepalive_count`)
|
||||
- Candidate mapping: advanced per-host connection tuning
|
||||
- Likely files: `backend/internal/caddy/types.go`,
|
||||
`backend/internal/caddy/config.go`, host settings API + UI
|
||||
2. `trusted_proxies_unix`
|
||||
- Candidate mapping: trusted local socket proxy chains
|
||||
- Current `TrustedProxies` struct lacks explicit unix-socket trust fields
|
||||
3. Certificate lifecycle tunables (`renewal_window_ratio`, maintenance interval)
|
||||
- Candidate mapping: advanced TLS policy controls
|
||||
- Potentially belongs under system-level TLS settings, not per-host UI
|
||||
|
||||
#### Features likely backend-only / no new UI by default
|
||||
|
||||
1. Reverse-proxy automatic `Host` rewrite for TLS upstreams
|
||||
2. ECH key auto-rotation
|
||||
3. `SIGUSR1` reload fallback behavior
|
||||
4. Logging backend internals (`timberjack`, ordering fixes)
|
||||
|
||||
Plan decision rule: expose only options that produce clear operator value and
|
||||
can be represented without adding UX complexity.
|
||||
|
||||
### Security patch relevance matrix
|
||||
|
||||
#### Advisory exploitability rubric and ownership
|
||||
|
||||
Use the following deterministic rubric for each advisory before any promotion:
|
||||
|
||||
| Field | Required Values | Rule |
|
||||
| --- | --- | --- |
|
||||
| Exploitability | `Affected` / `Not affected` / `Mitigated` | `Affected` means a reachable vulnerable path exists in Charon runtime; `Not affected` means required feature/path is not present; `Mitigated` means vulnerable path exists upstream but Charon deployment/runtime controls prevent exploitation. |
|
||||
| Evidence source | advisory + code/config/runtime proof | Must include at least one authoritative upstream source (GitHub advisory/Caddy release) and one Charon-local proof (config path, test, scan, or runtime verification). |
|
||||
| Owner | named role | Security owner for final disposition (`QA_Security` lead or delegated maintainer). |
|
||||
| Recheck cadence | `weekly` / `release-candidate` / `on-upstream-change` | Minimum cadence: weekly until CVE enrichment is complete and disposition is stable for two consecutive checks. |
|
||||
|
||||
Promotion gate: every advisory must have all four fields populated and signed by
|
||||
owner in the PR evidence bundle.
|
||||
|
||||
#### High-priority for Charon context
|
||||
|
||||
1. `GHSA-879p-475x-rqh2` (admin API cross-origin no-cors)
|
||||
- Charon binds admin API internally but still uses `0.0.0.0:2019` in
|
||||
generated config. Must verify actual network isolation and container
|
||||
exposure assumptions.
|
||||
2. `GHSA-hffm-g8v7-wrv7` (mTLS fail-open)
|
||||
- Relevant if client-auth CA pools are configured anywhere in generated or
|
||||
imported config paths.
|
||||
3. matcher bypass advisories (`GHSA-x76f-jf84-rqj8`, `GHSA-g7pc-pc7g-h8jh`)
|
||||
- Potentially relevant to host/path-based access control routing in Caddy.
|
||||
|
||||
#### Contextual/conditional relevance
|
||||
|
||||
- `GHSA-5r3v-vc8m-m96g` (FastCGI split_path)
|
||||
- Relevant only if FastCGI transport is in active use.
|
||||
- `GHSA-4xrr-hq4w-6vf4` (file matcher glob sanitization)
|
||||
- Relevant when file matchers are used in route logic.
|
||||
|
||||
### xcaddy patch retirement candidates
|
||||
|
||||
#### Candidate to re-evaluate for removal
|
||||
|
||||
- `go get github.com/slackhq/nebula@v1.9.7`
|
||||
- Upstream Caddy has moved forward to `nebula v1.10.3` and references
|
||||
security-related maintenance in the 2.11.x line.
|
||||
- Existing Charon pin comment may be stale after upstream smallstep updates.
|
||||
|
||||
#### Likely retain until proven redundant
|
||||
|
||||
- `go get github.com/expr-lang/expr@v1.17.7`
|
||||
- `go get github.com/hslatman/ipstore@v0.4.0`
|
||||
|
||||
Retention/removal decision must be made using reproducible build + binary
|
||||
inspection evidence, not assumption.
|
||||
|
||||
#### Hard retirement gates (mandatory before removing any pin)
|
||||
|
||||
Pin removal is blocked unless all gates pass:
|
||||
|
||||
1. Binary module diff gate
|
||||
- Produce before/after `go version -m` module diff for Caddy binary.
|
||||
- No unexpected module major-version jumps outside approved advisory scope.
|
||||
2. Security regression gate
|
||||
- No new HIGH/CRITICAL findings in CodeQL/Trivy/Grype compared to baseline.
|
||||
3. Reproducible build parity gate
|
||||
- Two clean rebuilds produce equivalent module inventory and matching runtime
|
||||
smoke results.
|
||||
4. Rollback proof gate (mandatory, with explicit `nebula` focus)
|
||||
- Demonstrate one-command rollback to previous pin set, with successful
|
||||
compile + runtime smoke set after rollback.
|
||||
|
||||
Retirement decision for `nebula` cannot proceed without explicit rollback proof
|
||||
artifact attached to PR evidence.
|
||||
|
||||
### Feature-to-control mapping (exposure decision matrix)
|
||||
|
||||
| Feature | Control surface | Expose vs backend-only rationale | Persistence path |
|
||||
| --- | --- | --- | --- |
|
||||
| `keepalive_idle`, `keepalive_count` | Existing advanced system settings (if approved) | Expose only if operators need deterministic upstream connection control; otherwise keep backend defaults to avoid UX bloat. | `frontend/src/pages/SystemSettings.tsx` → `frontend/src/api/settings.ts` → `backend/internal/api/handlers/settings_handler.go` → DB settings → `backend/internal/caddy/config.go` (`GenerateConfig`) |
|
||||
| `trusted_proxies_unix` | Backend-only default initially | Backend-only until proven demand for unix-socket trust tuning; avoid misconfiguration risk in general UI. | backend config model (`backend/internal/caddy/types.go`) + generated config path (`backend/internal/caddy/config.go`) |
|
||||
| `renewal_window_ratio`, cert maintenance interval | Backend-only policy | Keep backend-only unless operations requires explicit lifecycle tuning controls. | settings store (if introduced) → `settings_handler.go` → `GenerateConfig` |
|
||||
| Reverse-proxy Host rewrite / ECH rotation / reload fallback internals | Backend-only | Operational internals with low direct UI value; exposing would increase complexity without clear user benefit. | backend runtime defaults and generated Caddy config only |
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Test-first Repro and Baseline
|
||||
### Phase 1: Playwright and behavior baselining (mandatory first)
|
||||
|
||||
1. Confirm current failure (already reproduced).
|
||||
2. Record failing subtests and error signatures as baseline evidence.
|
||||
Objective: capture stable pre-upgrade behavior and ensure UI/UX parity checks.
|
||||
|
||||
### Phase 2: Minimal Remediation
|
||||
1. Run targeted E2E suites covering Caddy-critical flows:
|
||||
- `tests/tasks/import-caddyfile.spec.ts`
|
||||
- `tests/security-enforcement/zzz-caddy-imports/*.spec.ts`
|
||||
- system settings-related tests around Caddy admin API and SSL provider
|
||||
2. Capture baseline artifacts:
|
||||
- Caddy import warning behavior
|
||||
- security settings save/reload behavior
|
||||
- admin API connectivity assumptions from test fixtures
|
||||
3. Produce a baseline report in `docs/reports/` for diffing in later phases.
|
||||
|
||||
1. Apply preferred test expectation update in
|
||||
`backend/internal/services/proxyhost_service_validation_test.go`.
|
||||
2. Keep service code unchanged unless product intent is clarified otherwise.
|
||||
### Phase 2: Backend and build compatibility research implementation
|
||||
|
||||
### Phase 3: Targeted Validation
|
||||
Objective: validate compile/runtime compatibility of Caddy 2.11.1 with current
|
||||
plugin set and patch set.
|
||||
|
||||
Run in this order:
|
||||
1. Bump candidate in `Dockerfile`:
|
||||
- `ARG CADDY_VERSION=2.11.1`
|
||||
2. Execute matrix builds with toggles:
|
||||
- Scenario A: current patch set unchanged
|
||||
- Scenario B: remove `nebula` pin only
|
||||
- Scenario C: remove `nebula` + retain `expr/ipstore`
|
||||
3. Execute explicit compatibility gate matrix (deterministic):
|
||||
|
||||
1. `go test ./backend/internal/services -run TestProxyHostService_ValidateHostname -v`
|
||||
2. Related service package tests:
|
||||
- `go test ./backend/internal/services -run TestProxyHostService -v`
|
||||
- `go test ./backend/internal/services -v`
|
||||
3. Final gate:
|
||||
- `bash scripts/go-test-coverage.sh`
|
||||
| Dimension | Values |
|
||||
| --- | --- |
|
||||
| Plugin set | `caddy-security`, `coraza-caddy`, `caddy-crowdsec-bouncer`, `caddy-geoip2`, `caddy-ratelimit` |
|
||||
| Patch scenario | `A` current pins, `B` no `nebula` pin, `C` no `nebula` pin + retained `expr/ipstore` pins |
|
||||
| Platform/arch | `linux/amd64`, `linux/arm64` |
|
||||
| Runtime smoke set | boot Caddy, apply generated config, admin API health, import preview, one secured proxy request path |
|
||||
|
||||
## Risk Assessment
|
||||
Deterministic pass/fail rule:
|
||||
- **Pass**: all plugin modules compile/load for the matrix cell AND all smoke
|
||||
tests pass.
|
||||
- **Fail**: any compile/load error, missing module, or smoke failure.
|
||||
|
||||
### Key Risks
|
||||
Promotion criteria:
|
||||
- PR-1 promotion requires 100% pass for Scenario A on both architectures.
|
||||
- Scenario B/C may progress only as candidate evidence; they cannot promote to
|
||||
default unless all hard retirement gates pass.
|
||||
4. Validate generated binary dependencies from CI/local:
|
||||
- verify `expr`, `ipstore`, `nebula`, `smallstep/certificates` versions
|
||||
5. Validate runtime config application path:
|
||||
- `backend/internal/caddy/manager.go` → `ApplyConfig(ctx)`
|
||||
- `backend/internal/caddy/config.go` → `GenerateConfig(...)`
|
||||
6. Run Caddy package tests and relevant integration tests:
|
||||
- `backend/internal/caddy/*`
|
||||
- security middleware integration paths that rely on Caddy behavior
|
||||
|
||||
1. **Semantic risk (low):** updating tests could mask an intended behavior
|
||||
change if malformed URL permissiveness was deliberate.
|
||||
2. **Coverage risk (low):** test expectation changes may alter branch coverage
|
||||
marginally but should not threaten gate based on current context.
|
||||
3. **Regression risk (low):** service runtime behavior remains unchanged in the
|
||||
preferred path.
|
||||
### Phase 3: Security hardening and vulnerability posture updates
|
||||
|
||||
### Mitigations
|
||||
Objective: translate upstream advisories into Charon policy and tests.
|
||||
|
||||
- Keep change surgical to two table entries.
|
||||
- Preserve existing invalid-character rejection coverage.
|
||||
- Require full service package run plus coverage script before merge.
|
||||
1. Add/adjust regression tests for advisory-sensitive behavior in
|
||||
`backend/internal/caddy` and integration test suites, especially:
|
||||
- host matcher behavior with large host lists
|
||||
- escaped path matcher handling
|
||||
- admin API cross-origin assumptions
|
||||
2. Update security documentation and operational guidance:
|
||||
- identify which advisories are mitigated by upgrade alone
|
||||
- identify deployment assumptions (e.g., local admin API exposure)
|
||||
3. Introduce watchlist process for RESERVED CVEs pending NVD enrichment:
|
||||
- monitor Caddy advisories and module-level disclosures weekly
|
||||
|
||||
## Rollback Plan
|
||||
### Phase 4: Frontend and API exposure decisions (only if justified)
|
||||
|
||||
If maintainer/product decision confirms permissive malformed URL handling is
|
||||
required:
|
||||
Objective: decide whether 2.11.x features merit UI controls.
|
||||
|
||||
1. Revert the test expectation update commit.
|
||||
2. Implement minimal service normalization change in
|
||||
`backend/internal/services/proxyhost_service.go`.
|
||||
3. Add explicit tests documenting the accepted malformed-input behavior and
|
||||
retain strict negative tests for illegal hostname characters.
|
||||
4. Re-run targeted validation commands and coverage gate.
|
||||
1. Evaluate additions to existing `SystemSettings` UX only (no new page):
|
||||
- optional advanced toggles for keepalive tuning and trusted proxy unix scope
|
||||
2. Add backend settings keys and mapping only where persisted behavior is
|
||||
needed:
|
||||
- settings handler support in
|
||||
`backend/internal/api/handlers/settings_handler.go`
|
||||
- propagation to config generation in `GenerateConfig(...)`
|
||||
3. If no high-value operator need is proven, keep features backend-default and
|
||||
document rationale.
|
||||
|
||||
### Phase 5: Validation, docs, and release readiness
|
||||
|
||||
Objective: ensure secure, reversible, and auditable rollout.
|
||||
|
||||
1. Re-run full DoD sequence (E2E, patch report, security scans, coverage).
|
||||
2. Update architectural docs if behavior/config model changes.
|
||||
3. Publish release decision memo:
|
||||
- accepted changes
|
||||
- rejected/deferred UX features
|
||||
- retained/removed patches with evidence
|
||||
|
||||
## PR Slicing Strategy
|
||||
|
||||
Decision: **Single PR**.
|
||||
### Decision
|
||||
|
||||
Rationale:
|
||||
Use **multiple PRs (PR-1/PR-2/PR-3)**.
|
||||
|
||||
- Scope is tightly bounded to one service test suite and one failure cluster.
|
||||
- Preferred remediation is test-only with low rollback complexity.
|
||||
- Review surface is small and dependency-free.
|
||||
Reasoning:
|
||||
|
||||
Contingency split trigger:
|
||||
1. Work spans infra/build security + backend runtime + potential frontend UX.
|
||||
2. Caddy is a blast-radius-critical dependency; rollback safety is mandatory.
|
||||
3. Review quality and CI signal are stronger with isolated, testable slices.
|
||||
|
||||
- Only split if product intent forces service logic change, in which case:
|
||||
- PR-1: test expectation alignment rollback + service behavior decision record
|
||||
- PR-2: minimal service correction + adjusted tests
|
||||
### PR-1: Compatibility and evidence foundation
|
||||
|
||||
## Config/Infra File Impact Review
|
||||
Scope:
|
||||
|
||||
Reviewed for required updates:
|
||||
- `Dockerfile` Caddy candidate bump (and temporary feature branch matrix toggles)
|
||||
- CI/workflow compatibility instrumentation if needed
|
||||
- compatibility report artifacts and plan-linked documentation
|
||||
|
||||
- `.gitignore`
|
||||
- `.dockerignore`
|
||||
- `codecov.yml`
|
||||
- `Dockerfile`
|
||||
Dependencies:
|
||||
|
||||
Planned changes: **None required** for this focused backend test-remediation
|
||||
scope.
|
||||
- None
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
1. Caddy 2.11.1 compiles with existing plugin set under at least one stable
|
||||
patch scenario.
|
||||
2. Compatibility gate matrix (plugin × patch scenario × platform/arch × runtime
|
||||
smoke set) executed with deterministic pass/fail output and attached evidence.
|
||||
3. Binary module inventory report generated and attached.
|
||||
4. No production behavior changes merged beyond compatibility scaffolding.
|
||||
|
||||
Release guard (mandatory for PR-1):
|
||||
|
||||
- Candidate tag only (`*-rc`/`*-candidate`) is allowed.
|
||||
- Release pipeline exclusion is required; PR-1 artifacts must not be eligible
|
||||
for production release jobs.
|
||||
- Promotion to releasable tag is blocked until PR-2 security/retirement gates
|
||||
pass.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Revert `Dockerfile` arg changes and instrumentation only.
|
||||
|
||||
### PR-2: Security patch posture + patch retirement decision
|
||||
|
||||
Scope:
|
||||
|
||||
- finalize retained/removed `go get` patch lines in `Dockerfile`
|
||||
- update security tests/docs tied to six Caddy advisories
|
||||
- tighten/confirm admin API exposure assumptions
|
||||
|
||||
Dependencies:
|
||||
|
||||
- PR-1 evidence
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
1. Decision logged for each patch (`expr`, `ipstore`, `nebula`) with rationale.
|
||||
2. Advisory coverage matrix completed with Charon applicability labels.
|
||||
3. Security scans clean at required policy thresholds.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Revert patch retirement lines and keep previous pinned patch model.
|
||||
|
||||
### PR-3: Optional UX/API exposure and cleanup
|
||||
|
||||
Scope:
|
||||
|
||||
- only approved high-value settings exposed in existing settings surface
|
||||
- backend mapping and frontend wiring using existing settings flows
|
||||
- docs and translations updates if UI text changes
|
||||
|
||||
Dependencies:
|
||||
|
||||
- PR-2 must establish stable runtime baseline first
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
1. No net-new page; updates land in existing `SystemSettings` domain.
|
||||
2. E2E and unit tests cover newly exposed controls and defaults.
|
||||
3. Deferred features explicitly documented with rationale.
|
||||
|
||||
Rollback notes:
|
||||
|
||||
- Revert UI/API additions while retaining already landed security/runtime upgrades.
|
||||
|
||||
## Config File Review and Proposed Updates
|
||||
|
||||
### Dockerfile (required updates)
|
||||
|
||||
1. Update `ARG CADDY_VERSION` target to `2.11.1` after PR-1 gating.
|
||||
2. Reassess and potentially remove stale `nebula` pin in caddy-builder stage
|
||||
if matrix build proves compatibility and security posture improves.
|
||||
3. Keep `expr`/`ipstore` patch enforcement until binary inspection proves
|
||||
upstream transitive versions are consistently non-vulnerable.
|
||||
|
||||
### .gitignore (suggested updates)
|
||||
|
||||
No mandatory update for rollout, but recommended if new evidence artifacts are
|
||||
generated in temporary paths:
|
||||
|
||||
- ensure transient compatibility artifacts are ignored (for example,
|
||||
`test-results/caddy-compat/**` if used).
|
||||
|
||||
### .dockerignore (suggested updates)
|
||||
|
||||
No mandatory update; current file already excludes heavy test/docs/security
|
||||
artifacts and keeps build context lean. Revisit only if new compatibility
|
||||
fixture directories are introduced.
|
||||
|
||||
### codecov.yml (suggested updates)
|
||||
|
||||
No mandatory change for version upgrade itself. If new compatibility harness
|
||||
tests are intentionally non-coverage-bearing, add explicit ignore patterns to
|
||||
avoid noise in project and patch coverage reports.
|
||||
|
||||
## Risk Register and Mitigations
|
||||
|
||||
1. Plugin/API incompatibility with Caddy 2.11.1
|
||||
- Mitigation: matrix compile + targeted runtime tests before merge.
|
||||
2. False confidence from scanner-only dependency policies
|
||||
- Mitigation: combine advisory-context review with binary-level inspection.
|
||||
3. Behavioral drift in reverse proxy/matcher semantics
|
||||
- Mitigation: baseline E2E + focused security regression tests.
|
||||
4. UI sprawl from exposing too many Caddy internals
|
||||
- Mitigation: only extend existing settings surface when operator value is
|
||||
clear and validated.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. `TestProxyHostService_ValidateHostname` passes, including malformed URL
|
||||
subtests.
|
||||
2. `go test ./backend/internal/services -run TestProxyHostService -v` passes.
|
||||
3. `go test ./backend/internal/services -v` passes.
|
||||
4. `bash scripts/go-test-coverage.sh` passes final gate.
|
||||
5. Root cause is documented as expectation drift vs. service behavior drift, and
|
||||
chosen path is explicitly recorded.
|
||||
1. Charon builds and runs with Caddy 2.11.1 and current plugin set under
|
||||
deterministic CI validation.
|
||||
2. A patch disposition table exists for `expr`, `ipstore`, and `nebula`
|
||||
(retain/remove/replace + evidence).
|
||||
3. Caddy advisory applicability matrix is documented, including exploitability
|
||||
notes for Charon deployment model.
|
||||
4. Any added settings are mapped end-to-end:
|
||||
frontend state → API payload → persisted setting → `GenerateConfig(...)`.
|
||||
5. E2E, security scans, and coverage gates pass without regression.
|
||||
6. PR-1/PR-2/PR-3 deliverables are independently reviewable and rollback-safe.
|
||||
|
||||
## Handoff
|
||||
|
||||
After approval of this plan:
|
||||
|
||||
1. Delegate PR-1 execution to implementation workflow.
|
||||
2. Require evidence artifacts before approving PR-2 scope reductions
|
||||
(especially patch removals).
|
||||
3. Treat PR-3 as optional and value-driven, not mandatory for the security
|
||||
update itself.
|
||||
|
||||
Reference in New Issue
Block a user