CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-27585
6.90.04%

Backslash Blues: Bypassing Caddy's ACLs with a Single Character

Alon Barad
Alon Barad
Software Engineer

Feb 25, 2026·6 min read·8 visits

PoC Available

Executive Summary (TL;DR)

Caddy < 2.11.1 failed to escape backslashes in its `file` matcher sanitization. Attackers can use paths like `/admi\n` to bypass explicit block rules for `/admin`, as the filesystem globber interprets the escaped character literally, serving the protected file.

A semantic gap between Caddy's HTTP request matching and the underlying Go filesystem globbing logic allows attackers to bypass path-based access controls. By injecting backslashes into the request URI, an attacker can evade security matchers while still successfully resolving the target file on disk.

The Hook: When Is a File Not a File?

Caddy is the darling of the modern web server world—automatic HTTPS, clean config syntax, and usually, secure defaults. But like any complex piece of software sitting at the boundary between the wild internet and your dusty filesystem, it faces a classic problem: translation errors.

In web security, we often talk about "semantic gaps" or "parser differentials." This happens when two different parts of a system interpret the same piece of data in two different ways. The firewall thinks the packet is safe, but the kernel thinks it's a command. In Caddy's case, the differential lies between the HTTP request matcher (which decides if you can see a file) and the file matcher (which decides which file to show you).

CVE-2026-27585 is a beautiful, textbook example of this. It's not a memory corruption bug. It's not a buffer overflow. It's a logic error where a single character—the humble backslash—lets us walk right past the bouncer.

The Flaw: The Great Escape

To understand this bug, you have to look at how Caddy handles the try_files directive and the file matcher. When you tell Caddy to check if a file exists, it often takes the URL path and runs it against the filesystem. But filesystems are weird. They support "globbing"—wildcards like * (match anything) or ? (match one character).

If a user requests /images/*, and Caddy passes that directly to the filesystem, the OS might dutifully list every file in the directory. That's bad. So, Caddy implements a sanitizer called globSafeRepl. Its job is to neuter these special characters before they hit the disk logic.

Here is where the developers tripped. They remembered to escape the obvious wildcards: asterisks, question marks, and brackets. But they forgot the master key of globbing: the escape character itself, the backslash (\).

In Go's path/filepath.Glob implementation (and many others), a backslash is used to escape the next character. So, \* means "literal asterisk", not wildcard. But crucially, \a just means "literal a". This creates our bypass mechanism. To the HTTP matcher, /admi\n is a completely different string than /admin. But to the globber, they are identical.

The Code: The Smoking Gun

The vulnerability lived in modules/caddyhttp/fileserver/matcher.go. The globSafeRepl function was responsible for making paths safe for globbing. Let's look at the diff found in commit 68d50020eef0d4c3398b878f17c8092ca5b58ca0.

The Vulnerable Code:

// It escapes *, ?, and [ but leaves \ alone
var globSafeRepl = strings.NewReplacer(
    "*", "\\*",
    "?", "\\?",
    "[", "\\[",
)

Because the backslash wasn't in this list, a user input of foo\bar would remain foo\bar. When passed to filepath.Glob, that backslash would escape the b.

The Fix (v2.11.1):

// Now escaping the escape character itself
var globSafeRepl = strings.NewReplacer(
    "*", "\\*",
    "?", "\\?",
    "[", "\\[",
    "\\", "\\\\", // <--- The fix
)

It's a one-line fix, as most critical logic bugs are. By turning \ into \\, Caddy ensures that the globber sees a literal backslash, rather than interpreting it as an escape sequence. Now, /admi\n becomes /admi\\n, which the filesystem looks for literally—and fails to find (unless you have a file named admi\n on disk, in which case, you have other problems).

The Exploit: Walking Past the Bouncer

Let's construct a realistic attack scenario. Imagine a system administrator has set up a Caddy server with a blocklist for a sensitive directory, but uses try_files to serve content.

Vulnerable Configuration:

example.com {
    # 1. Security Rule: Block access to /secret
    @blocked {
        path /secret/*
    }
    respond @blocked 403
 
    # 2. File Server: Try to find the file
    try_files {path} /index.php
    file_server
}

The Attack Chain:

  1. Normal Request: The attacker requests GET /secret/password.txt. The @blocked matcher sees the path starts with /secret/. The request is denied (403).
  2. Bypass Attempt: The attacker requests GET /secre\t/password.txt.
  3. Matcher Check: The @blocked matcher compares /secre\t/ against /secret/. They do not match. The request is allowed to proceed.
  4. File Resolution: The request hits try_files. The placeholder {path} expands to /secre\t/password.txt.
  5. Globbing Magic: Caddy's (vulnerable) sanitizer leaves the backslash alone. The path is passed to Go's filepath.Glob. The globber reads \t as an escaped literal t.
  6. Success: The globber resolves the path to /secret/password.txt on the disk. Caddy serves the file.

We have successfully accessed a protected resource by exploiting the discrepancy between string comparison and filesystem globbing logic.

The Impact: Why Should We Panic?

This is a High Integrity impact vulnerability. While it doesn't give you Remote Code Execution (RCE) directly, it completely undermines the access control mechanisms that administrators rely on.

If you use Caddy as a reverse proxy or file server and rely on path matchers to restrict access to sensitive admin panels, config files, or internal metrics, this vulnerability renders those rules useless against a competent attacker.

It is particularly dangerous because it requires no authentication and no complex memory corruption techniques. It works on the default configuration logic that many tutorials suggest. The only saving grace is that it requires the specific combination of a path-based blocklist and a file matcher (or try_files) that processes the same input.

The Fix: Closing the Window

The mitigation is straightforward: Update to Caddy v2.11.1. This version includes the patch that correctly sanitizes backslashes in the file matcher.

If you cannot update immediately, you must sanitize the input at the edge. If you are running Caddy behind a cloud load balancer or another proxy (like Nginx), configure that upstream proxy to reject URIs containing backslashes (%5C). Alternatively, you can attempt to rewrite the request within Caddy before it hits the matcher logic, but this is error-prone. The binary update is the only robust fix.

> [!NOTE] > This fix demonstrates the importance of "defense in depth." Relying solely on path matching for security is brittle. Whenever possible, move sensitive files out of the web root entirely, rather than relying on the web server to block access to them.

Official Patches

CaddyOfficial Release Notes v2.11.1

Fix Analysis (1)

Technical Appendix

CVSS Score
6.9/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P
EPSS Probability
0.04%
Top 100% most exploited
150,000
Estimated exposed hosts via Shodan

Affected Systems

Caddy Server < 2.11.1

Affected Versions Detail

Product
Affected Versions
Fixed Version
Caddy
Caddy Web Server
< 2.11.12.11.1
AttributeDetail
CWECWE-20 (Improper Input Validation)
CVSS v4.06.9 (Medium)
Attack VectorNetwork
Attack ComplexityLow
Privileges RequiredNone
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1006Direct Volume Access
Defense Evasion
CWE-20
Improper Input Validation

Improper Input Validation

Known Exploits & Detection

Internal ResearchPath traversal/bypass via backslash injection in try_files
NucleiDetection Template Available

Vulnerability Timeline

Fix committed to master branch
2026-02-16
CVE-2026-27585 Published
2026-02-24
Caddy v2.11.1 Released
2026-02-24

References & Sources

  • [1]NVD Entry
  • [2]GitHub Security Advisory

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.