GITHUB.COM/CADDYSERVER/CADDY/V2 · GHSA-25cw-38mq-q7m6 · Package
FIX → 2.11.8
Caddy's file matcher turns a request like /.env/./ into the regular file /.env, so path rules written to block that file are skipped. An unauthenticated client can read blocked static files such as .env, backups or configuration.
first public Nov 4, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Sites served by Caddy where a try_files {path} rewrite runs before file_server, or where php_fastcgi or php_server is used, and where path rules are meant to block certain files. Servers that do not use try_files {path} or rely only on prefix rules or directory-wide regex blocks are less exposed. Managed hosting that does not expose the Caddyfile is not affected by the config pattern.
Not affected if managed-hosting, no-try-files-path, prefix-rules-only
Who cares caddy, frankenphp, php, self-hosted
caddy version and compare against the fixed release.try_files {path} combined with path or path_regexp block rules, or for php_fastcgi or FrankenPHP php_server followed by file_server.try_files {path} resolves /.env/./ to the regular file /.env, while path matchers see /.env/. A rule such as path *.env placed before the rewrite doesn't match, and file_server serves the file without its canonical redirect. php_fastcgi and FrankenPHP's php_server are affected through their built-in try_files route.
The file matcher (modules/caddyhttp/fileserver/matcher.go) runs path.Clean on each expanded candidate, which drops the trailing slash, and restores it only when the try_files pattern itself ends in /. So try_files {path} resolves to the regular file and rewrites the request to it.
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
Upgrade to 2.11.8
2.11.8/.env/.//.envPath matchers see /.env/ for that request, so suffix rules, exact paths, globs ending in a file name and $-anchored path_regexp evaluated before the rewrite don't match. file_server then skips its canonical redirect because path.Base of the original path (.) and of the rewritten path (.env) differ, and serves the file.
Fix: keep the trailing slash of the expanded candidate through path.Clean. strictFileExists already requires a candidate ending in / to be a directory, so /.env/ and /.env/./ no longer match the regular file, while /dir/./ still matches the directory and split_path keeps working. Patch: public PR from dunglas:fileserver-match-trailing-slash.
Discovered by Anthropic's OSS Scanner, as vulnerability ANT-2026-VAGWNYYZ.
:8080 {
root /srv
@blocked path *.env
route {
respond @blocked 403
try_files {path} {path}/ /index.html
file_server
}
}
$ curl -i localhost:8080/.env # 403
$ curl -i --path-as-is localhost:8080/.env/./ # 200, body of /srv/.env
The same works with php_fastcgi followed by file_server.
Unauthenticated clients read static files (.env, backups, configuration) that a suffix or exact path rule is meant to block. Prefix rules and */.* still block. Nothing gets executed.