CVEReports
CVEReports

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

Product

  • Home
  • 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-27588

Case Sensitive Chaos: Bypassing Caddy Authentication with a Shift Key

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 25, 2026·6 min read·47 visits

Executive Summary (TL;DR)

If you have more than 100 hosts in a Caddy block, the server switches to a 'fast path' that forgets how to read uppercase letters. Attackers can bypass host-based authentication by sending `Host: ADMIN.EXAMPLE.COM` instead of `admin.example.com`. Upgrade to 2.11.1 immediately.

A logic error in Caddy's HTTP host matcher allows attackers to bypass routing rules and associated security middleware (like authentication) by simply changing the capitalization of the Host header. This vulnerability specifically affects configurations with more than 100 hostnames, where an optimization path inadvertently switches from case-insensitive to case-sensitive matching.

The Hook: Premature Optimization

In the world of software engineering, there is an old adage: "Premature optimization is the root of all evil." In the world of exploit development, we call it "job security." Caddy, the darling of modern web servers known for its automatic HTTPS and ease of use, recently fell victim to this exact trap. It wasn't a memory corruption bug, a buffer overflow, or some complex race condition. It was a simple attempt to make the server go vroom when handling large lists of domains.

The vulnerability, tracked as CVE-2026-27588, is a classic logic flaw hidden inside a performance optimization. Web standards (RFC 4343) dictate that domain names are case-insensitive. example.com, Example.Com, and ExAmPlE.cOm are all the same place. Caddy knows this. Caddy respects this. Usually.

However, someone decided that when a single matcher block contains more than 100 hostnames—a common scenario for SaaS providers or multi-tenant architectures—a linear scan was too slow. They implemented a binary search optimization. The problem? Computers are pedantic. While a linear scan using strings.EqualFold knows that 'A' equals 'a', a binary search relying on standard string sorting and equality checks does not. This created a split-brain scenario where the server's security posture depended entirely on how many domains you shoved into your config file.

The Flaw: The 101st Host

Let's dig into the root cause. Caddy's MatchHost module is responsible for looking at an incoming HTTP request, grabbing the Host header, and deciding if it matches a rule. If you have a rule saying "Require Basic Auth for admin.corp.com," Caddy checks the header. If the header matches, the middleware chain executes, and the user is prompted for a password.

Here is where the logic splits. If you have 100 or fewer hosts defined, Caddy iterates through them one by one, performing a case-insensitive comparison. This is safe. However, if you add that 101st host, Caddy switches to an "optimized" path. This path sorts the list of hosts and uses sort.Search to find the target.

The fatal flaw was in the comparison logic used during this binary search. The code compared the incoming Host header directly against the stored configuration using Go's == operator. In Go, "example.com" == "EXAMPLE.COM" evaluates to false.

This means if an attacker sends a request to ADMIN.CORP.COM, the optimized matcher looks at its sorted list of lowercase domains, sees admin.corp.com, compares it to ADMIN.CORP.COM, determines they are different, and returns false. The matcher fails. The request is not considered a match for that block.

The Code: The Smoking Gun

The vulnerability lived in modules/caddyhttp/matchers.go. It’s a perfect example of how a subtle assumption can break security boundaries. Here is the vulnerable logic from versions prior to 2.11.1:

// VULNERABLE CODE
if m.large() {
    // fast path: locate exact match using binary search
    pos := sort.Search(len(m), func(i int) bool {
        // comparison is case-SENSITIVE
        return m[i] >= reqHost 
    })
    // equality check is case-SENSITIVE
    if pos < len(m) && m[pos] == reqHost { 
        return true, nil
    }
}

The fix was embarrassingly simple: normalize everything to lowercase before comparing. The patch ensures that no matter how the user types the domain, the binary search sees a lowercase string, matching the normalized configuration.

// PATCHED CODE (v2.11.1)
if m.large() {
    // Normalize the input before search
    reqHostLower := strings.ToLower(reqHost)
    pos := sort.Search(len(m), func(i int) bool {
        return m[i] >= reqHostLower
    })
    if pos < len(m) && m[pos] == reqHostLower {
        return true, nil
    }
}

This change restores the RFC-compliant behavior even when the optimization path is triggered.

The Exploit: Bypassing the Bouncer

So, how do we weaponize this? The impact depends entirely on what the matcher is guarding. In Caddy, matchers are often used as gates for middleware. A common pattern is to apply authentication only to specific internal subdomains.

The Setup: Imagine a SaaS platform using Caddy with 150 customer domains configured. One of them is internal-admin.saas.com, protected by basicauth.

The Attack:

  1. Standard Request: GET / HTTP/1.1 | Host: internal-admin.saas.com.

    • Caddy's binary search matches the host.
    • The basicauth middleware is triggered.
    • Result: 401 Unauthorized.
  2. Bypass Request: GET / HTTP/1.1 | Host: INTERNAL-ADMIN.SAAS.COM.

    • Caddy's binary search fails to match because of the case mismatch.
    • The matcher returns false.
    • The basicauth middleware is skipped because the matcher didn't trigger.
    • The request proceeds down the chain. If there is a catch-all route (e.g., *) or if the backend simply serves the app based on the Host header regardless of Caddy's routing logic, the attacker gains access.

This effectively turns a "secure" internal admin panel into a public-facing page, provided the backend application itself doesn't enforce a secondary layer of host validation (spoiler: they rarely do).

The Fix: Lowercase Everything

The mitigation is straightforward: Upgrade to Caddy v2.11.1. The Caddy team responded quickly once the issue was identified, patching the binary search logic to normalize the request host before lookup.

If you are stuck in a change-freeze or cannot upgrade immediately, there is a configuration workaround, though it is tedious. You need to ensure that no single host matcher block contains more than 100 entries.

For example, instead of:

@myhosts host a.com b.com ... (101 domains) ...

You would split it:

@group1 host a.com ... (50 domains)
@group2 host ... (51 domains)

This forces Caddy to use the unoptimized, linear scan path, which correctly uses strings.EqualFold and is not vulnerable to this casing bypass. But seriously, just upgrade the binary. It's a single file.

Official Patches

CaddyCaddy v2.11.1 Release Notes
GitHubCommit eec32a0 fixing the binary search logic

Fix Analysis (1)

Technical Appendix

CVSS Score
7.7/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P

Affected Systems

Caddy Web Server < 2.11.1

Affected Versions Detail

Product
Affected Versions
Fixed Version
Caddy
Caddy
< 2.11.12.11.1
AttributeDetail
CWE IDCWE-178 (Improper Handling of Case Sensitivity)
CVSS v4.07.7 (High)
Attack VectorNetwork (AV:N)
ImpactIntegrity High, Authorization Bypass
ConstraintRequires > 100 hosts in matcher config
Exploit StatusTrivial (Change Header Casing)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1566Modify Request Headers
Defense Evasion
CWE-178
Improper Handling of Case Sensitivity

The software does not correctly resolve the case sensitivity of inputs, leading to inconsistent logic or access control bypasses.

Known Exploits & Detection

HypotheticalChanging Host header casing to bypass authentication middleware on routes utilizing large host matchers.

Vulnerability Timeline

Fix commit pushed to repository
2026-02-20
Caddy v2.11.1 Released
2026-02-24
GHSA-x76f-jf84-rqj8 Published
2026-02-24

References & Sources

  • [1]GHSA-x76f-jf84-rqj8: Host matcher case sensitivity bypass
  • [2]NVD - CVE-2026-27588

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.

More Reports

•about 12 hours ago•CVE-2026-14669
8.8

CVE-2026-14669: PostgreSQL to_char() Timezone Abbreviation Heap-Based Buffer Overflow

CVE-2026-14669 is a critical heap-based buffer overflow vulnerability in PostgreSQL's date/time formatting function to_char(timestamptz). The flaw arises from unsafe copying of user-controlled timezone abbreviations into a fixed-size internal buffer. An authenticated database user can trigger this issue by setting a long POSIX timezone abbreviation containing custom formatting, allowing them to overwrite adjacent heap structures and hijack execution control to achieve remote code execution (RCE) with the privileges of the 'postgres' operating system user.

Alon Barad
Alon Barad
9 views•6 min read
•2 days ago•CVE-2026-63462
7.5

CVE-2026-63462: Unauthenticated Stack Overflow Denial of Service in Unleash Server

An unauthenticated remote denial of service vulnerability exists in the Unleash feature management platform. By submitting a crafted JSON payload containing deeply nested structures to an OpenAPI-validated endpoint, an attacker can trigger uncontrolled recursion within the error formatting module. This leads to a call-stack exhaustion (RangeError: Maximum call stack size exceeded) inside the Node.js runtime, causing the service to crash immediately without recovery.

Alon Barad
Alon Barad
11 views•6 min read
•2 days ago•CVE-2026-63004
5.5

CVE-2026-63004: Server-Side Request Forgery in Unleash Addon and Integration Subsystem

CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.

Amit Schendel
Amit Schendel
9 views•8 min read
•2 days ago•CVE-2026-63466
4.1

CVE-2026-63466: Process-Wide Security Degradation via Global Module Mutation in Unleash

Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.

Alon Barad
Alon Barad
3 views•6 min read
•2 days ago•CVE-2026-76904
9.8

CVE-2026-76904: Unauthenticated SQL Injection in GeoTools PostGIS DataStore Component

A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.

Alon Barad
Alon Barad
16 views•5 min read
•2 days ago•CVE-2026-61824
8.2

CVE-2026-61824: High-Severity Cross-Site Scripting (XSS) via Unsanitized Site Extractors in Defuddle

CVE-2026-61824 is a high-severity Cross-Site Scripting (XSS) vulnerability in kepano/defuddle before version 0.19.1. Custom site extractors for platforms such as X/Twitter, Substack, and YouTube constructed HTML representations via template string interpolation without output escaping. This allowed malicious pages to bypass standard parser sanitization routines and execute arbitrary JavaScript.

Amit Schendel
Amit Schendel
8 views•7 min read