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-77281

CVE-2026-77281: Rewrite Placeholder Re-expansion Vulnerability in Caddy Web Server

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 18, 2026·8 min read·4 visits

Executive Summary (TL;DR)

Caddy's rewrite engine double-evaluates placeholder expressions when rewrite directives end with a literal question mark. Remote attackers can exploit this by injecting placeholder tokens via HTTP headers to extract internal environment variables or read local system files.

A critical double-evaluation vulnerability exists in the rewrite module of the Caddy web server. Under specific configurations where a rewrite directive ends with a literal question mark and processes client-controlled headers, the system performs a secondary expansion pass. This allows attackers to evaluate arbitrary internal placeholder variables, leading to unauthorized disclosure of sensitive environment variables and system files.

Vulnerability Overview

Caddy is an extensible web server written in Go that relies on a structured modular architecture to process incoming HTTP traffic. A core mechanism within this architecture is the Replacer, which dynamically evaluates variable placeholders wrapped in curly braces. This mechanism is frequently used in routing configurations, reverse proxy operations, and rewrite directives to interpolate properties such as request headers, client IP addresses, or environment variables. This dynamic substitution provides administrators with configuration flexibility but also expands the attack surface if user-controlled input flows into the evaluation context.

The vulnerability classified as CVE-2026-77281 resides specifically within the request rewrite processing logic, implemented in modules/caddyhttp/rewrite/rewrite.go. Under typical operations, a rewrite directive modifies the URI of an active request before sending it to downstream handlers. When the rewrite rules utilize client-controlled variables, such as values parsed directly from incoming HTTP headers, Caddy is designed to perform a single substitution pass. However, a structural logic error allows an attacker to bypass this boundary.

By manipulating input headers and exploiting specific rewrite configurations that terminate with a literal question mark, an attacker can coerce the rewrite engine into performing a secondary evaluation pass. This secondary pass treats the resolved string as executable placeholder syntax rather than safe, static text. Consequently, any nested template token injected by the client is processed by the internal evaluation system. The primary impact of this flaw is unauthorized information disclosure, enabling attackers to leak cryptographic secrets, environment variables, or local files.

Root Cause Analysis

The root cause of CVE-2026-77281 is a double-evaluation flaw inside the query parameter separation logic of Caddy's rewrite module. When Caddy processes a rewrite directive, it initializes the Replacer engine to evaluate all defined placeholders. This step converts configuration parameters like {http.request.header.X-Fwd} into their literal string representations. If the rewrite path template terminates with a literal question mark, Caddy's parser performs a string-split operation to isolate the path from the query string.

The split mechanism is designed to handle rewrites where query parameters must be appended or overwritten. When a literal question mark is found, the parser divides the intermediate, post-evaluation URI into two distinct string variables: newPath and injectedQuery. If the configuration did not explicitly define an independent query string, the handler assigns the extracted injectedQuery to the request's internal query variable. This state transition is critical because the newly isolated query string contains raw, un-sanitized client input that has already undergone the first phase of template resolution.

Because of this architectural routing, the extracted query variable is subsequently passed to the buildQueryString function. The primary implementation defect exists here: buildQueryString executes a secondary ReplaceAll call on the query parameters. This secondary evaluation pass operates under the assumption that the input contains un-evaluated configuration-level placeholders. In reality, because of the split operation, the input now contains string content originating from the client, including any curly brace delimiters. Consequently, the Replacer parses these delimiters and evaluates the contained instructions.

Code and Data Flow Analysis

To understand the technical flow, it is helpful to analyze the structural changes applied to modules/caddyhttp/rewrite/rewrite.go. In the vulnerable implementation, the split output was directly assigned to the query variable without modification. The following code comparison highlights the vulnerability and the subsequent sanitation logic introduced in the fix.

// Vulnerable Implementation
newPath, injectedQuery = before, after
if query == "" {
    query = injectedQuery
}

In this state, any opening and closing curly braces present within injectedQuery remained unchanged. When query was evaluated in the downstream function, these characters triggered the Replacer's parser, which extracted the inner key and looked it up against registered system providers. The patched version mitigates this behavior by performing a global string replacement on the extracted substring before assigning it to the query variable.

// Patched Implementation (Caddy v2.11.4)
newPath, injectedQuery = before, after
if query == "" {
    // The injected query came from the first-pass placeholder
    // expansion above, which means any '{' or '}' bytes in it
    // must have come from replacement values (e.g. a request
    // header), not from operator-written placeholder syntax.
    // Escape them so buildQueryString does not re-expand them.
    injectedQuery = strings.ReplaceAll(injectedQuery, "{", "%7B")
    injectedQuery = strings.ReplaceAll(injectedQuery, "}", "%7D")
    query = injectedQuery
}

By replacing the literal curly braces with their percent-encoded representations (%7B and %7D), the patch ensures that the downstream evaluation pass is unable to recognize the character sequence as placeholder delimiters. The Replacer treats the percent-encoded values as safe, static string literals, preventing secondary execution. The following diagram illustrates this data flow during an exploitation attempt:

Exploitation and Proof-of-Concept Analysis

Exploitation of CVE-2026-77281 requires an attacker to satisfy two primary conditions. First, the target Caddy server must be configured with a rewrite rule that ends in a literal question mark and references a client-controlled variable. A common example is a reverse proxy or path router that utilizes incoming request headers to determine backend paths. Second, the attacker must have network access to transmit HTTP requests containing specifically formatted headers to the exposed Caddy listener.

The exploitation technique involves sending an HTTP request where the target header contains a nested placeholder string positioned immediately after a query delimiter. For example, an attacker targeting a header named X-Fwd would construct a payload value such as ok?key={env.CADDY_REWRITE_TEST_SECRET}. When the first-pass expansion occurs, this entire string is resolved as a path element. The split logic then extracts key={env.CADDY_REWRITE_TEST_SECRET} and treats it as a query parameter.

During the second evaluation pass within buildQueryString, Caddy's engine identifies the {env.CADDY_REWRITE_TEST_SECRET} syntax. It queries the system environment variables and replaces the token with the corresponding plaintext secret. If the rewritten request is subsequently forwarded to an upstream server controlled by the attacker, or if the server returns detailed error logs, the sensitive credentials are leaked. This allows unauthenticated, remote attackers to retrieve critical environmental configuration data without authorization.

Impact Assessment and Threat Modeling

The security impact of this vulnerability is primarily classified as low-to-medium-severity information disclosure, reflecting its CVSS score of 6.5. Although the flaw does not directly permit arbitrary code execution on the underlying operating system, the capability to leak environment variables significantly undermines system security. In modern cloud-native deployments, environment variables are frequently used to store sensitive configurations, including database connection strings, third-party API keys, and cryptographic secret keys.

Furthermore, the impact is compounded if specific optional modules are enabled on the Caddy server. For instance, if the local file provider is registered within Caddy's template engine, an attacker can use placeholders such as {file./etc/passwd} to read arbitrary local files. This escalates the vulnerability from basic environment variable disclosure to local file inclusion, potentially exposing sensitive system configuration files, private keys, or application source code.

The CVSS vector for this vulnerability (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L) underscores that the exploit is highly accessible. It requires no privileges, no user interaction, and has low technical complexity. While the integrity impact is rated as none, the availability impact is rated as low due to potential overhead or crash vectors associated with malformed placeholder parsing inside the core web server loop.

Remediation and Defensive Actions

The definitive resolution for CVE-2026-77281 is upgrading Caddy to version v2.11.4 or later. The patch introduces robust sanitization of the injected query string, preventing any secondary placeholder evaluation. Security administrators should prioritize updating their binary installations using official Caddy distribution channels to ensure all active rewrite loops are secured.

In scenarios where immediate patching is not technically feasible due to production change freezes or compatibility validations, administrative workarounds can be applied. Administrators should inspect their active Caddyfiles to locate rewrite directives that end with a literal question mark and rely on request variables. Modifying these rules to avoid passing client-supplied headers directly into the rewrite path terminates the attack vector.

Additionally, defense-in-depth measures can be deployed at the network layer. Web Application Firewalls (WAFs) should be configured to detect and block incoming HTTP requests containing curly braces inside common headers. A regular expression match targeting patterns like \{[a-zA-Z0-9_\.]+\} in request headers such as User-Agent, Referer, and custom routing headers can effectively neutralize incoming exploitation payloads before they reach the Caddy web server handler.

Official Patches

CaddyserverCaddy Security Advisory for GHSA-j8px-rmrx-76h9
CaddyserverCaddy Pull Request #7761

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L

Affected Systems

Caddy Web Server

Affected Versions Detail

Product
Affected Versions
Fixed Version
Caddy
Caddyserver
>= 2.8.3, < 2.11.42.11.4
AttributeDetail
CWE IDCWE-94
Attack VectorNetwork (AV:N)
CVSS Base Score6.5
Exploit StatusPoC-stage (Regression tests)
Affected ComponentCaddy rewrite module
ImpactInformation Disclosure (Environment variables, local files)

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1203Exploitation for Client Execution
Execution
CWE-94
Improper Control of Generation of Code ('Code Injection')

The software constructs code or execution logic using externally-influenced input, allowing attackers to execute arbitrary instructions or directives.

Known Exploits & Detection

GitHubOfficial regression test cases proving the double placeholder expansion payload behavior.

Vulnerability Timeline

Vulnerability identified and initial fix committed internally.
2026-05-26
Coordinated vulnerability disclosure of GHSA-j8px-rmrx-76h9 / CVE-2026-77281.
2026-09-17
Caddy version 2.11.4 released with the security fix.
2026-09-17

References & Sources

  • [1]https://github.com/caddyserver/caddy/security/advisories/GHSA-j8px-rmrx-76h9
  • [2]https://nvd.nist.gov/vuln/detail/CVE-2026-77281
  • [3]https://github.com/caddyserver/caddy/releases/tag/v2.11.4

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

•11 minutes ago•CVE-2025-53837
9.9

CVE-2025-53837: Remote Code Execution in XWiki Rendering via Macro Escape Injection

CVE-2025-53837 is a critical remote code execution (RCE) vulnerability in XWiki Rendering before versions 14.10.2 and 15.0 RC1. The vulnerability arises from a failure to escape macro closing tags within raw output handled by HTML macro blocks. This allows low-privilege users to escape the restricted HTML container and execute high-privilege scripts under the application's context.

Alon Barad
Alon Barad
1 views•4 min read
•about 2 hours ago•CVE-2026-77615
8.7

CVE-2026-77615: Stored Cross-Site Scripting (XSS) in Paella Player as used in Opencast

CVE-2026-77615 is a high-severity Stored Cross-Site Scripting (XSS) vulnerability in the Paella Player component, which is integrated as the default front-end media viewer in Opencast. Unsafe client-side rendering of subtitle tracks allows authenticated, low-privileged users to inject arbitrary JavaScript payloads via crafted WebVTT or DFXP files. The script executes within the context of any viewer session under the host origin, enabling session hijacking and unauthorized API interaction.

Alon Barad
Alon Barad
3 views•5 min read
•about 3 hours ago•GHSA-9395-2G46-RJ3F
8.2

GHSA-9395-2G46-RJ3F: Multiple Cross-Site Scripting (XSS) Vulnerabilities in djust Template and Live Engine

A comprehensive technical analysis of six Cross-Site Scripting (XSS) vulnerability classes in the djust framework versions 1.0.0 through 1.1.0, involving escaping failures across the Python-Rust template boundary and stateful WebSocket cache lifecycles.

Alon Barad
Alon Barad
4 views•10 min read
•about 4 hours ago•GHSA-XJW9-38CR-6372
8.2

GHSA-XJW9-38CR-6372: Cross-Site Scripting via Stale Safe-Key Inheritance in djust Template Shadowing

An escaping defect in the djust templating engine allows Cross-Site Scripting (XSS) when a template binding construct shadows a variable that was previously marked safe. The Rust-based context safety tracking incorrectly preserves name-based safety grants even after the variable name has been bound to a new, untrusted value.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 5 hours ago•CVE-2026-81875
7.5

CVE-2026-81875: Unbounded DEFLATE Decompression Denial of Service in HAPI FHIR SHCParser

A critical denial of service vulnerability exists in the HAPI FHIR SHCParser within the org.hl7.fhir.core Java library. Unbounded decompression of raw DEFLATE data during Smart Health Card parsing allows unauthenticated remote attackers to trigger JVM heap exhaustion and crash the application.

Alon Barad
Alon Barad
6 views•7 min read
•about 6 hours ago•CVE-2026-81876
7.5

CVE-2026-81876: Unauthenticated Denial of Service via Infinite Loop in HAPI FHIR SHCParser

CVE-2026-81876 is a high-severity Denial of Service vulnerability in HAPI FHIR, a complete Java implementation of the HL7 FHIR standard. The vulnerability stems from improper usage of Java's java.util.zip.Inflater class within the Smart Health Card (SHC) parser.

Amit Schendel
Amit Schendel
7 views•6 min read