Product Name: Caddy
Vendor: Caddy Server (Open Source)
Technology Stack: Go-based HTTP server and reverse proxy
Core Capabilities: Automatic HTTPS (ACME), HTTP/2 & HTTP/3, Reverse Proxy, FastCGI (PHP-FPM), mTLS authentication, JSON & Caddyfile configuration support
Deployment Context: Cloud-native workloads, containerized environments, Kubernetes ingress, edge reverse proxy, PHP hosting stacks
Caddy is widely deployed because of its default secure posture and automatic TLS provisioning. However, when request normalization or certificate validation logic behaves unexpectedly, high-impact security exposure may occur. The following two vulnerabilities affect request routing integrity and TLS authentication enforcement.
CVE-2026-27590 – Path Confusion Leading to Unintended PHP Execution (RCE)
Vulnerability Summary
| Field | Details |
|---|---|
| CVE ID | CVE-2026-27590 |
| Vulnerability Type | Path Traversal / Path Normalization Confusion |
| Impact | Remote Code Execution |
| CVSS Score | 9.1 (Critical) |
| Attack Vector | Network |
| Privileges Required | None |
| User Interaction | None |
| Severity | Critical |
| Exploitability | High |
| Exploit Availability | Proof-of-Concept observed in controlled research environments |
| Affected Component | HTTP path parsing & FastCGI handler logic |
Technical Description
In affected versions of Caddy, inconsistent handling of Unicode-encoded path separators and normalization routines was observed. When specially crafted Unicode characters resembling forward slashes or dot separators were embedded in HTTP request paths, discrepancies occurred between:
- Caddy’s internal router
- Filesystem path resolution
- FastCGI PHP handler processing
It was identified that path normalization occurred at different stages of request handling. Under specific encoding conditions, a request initially treated as a static file request could later be interpreted as a PHP script execution request.
This inconsistency allowed unintended routing into the PHP execution engine.
Root Cause Analysis
The issue stemmed from:
- Improper canonicalization of Unicode path separators (e.g., full-width slash U+FF0F).
- Multiple decoding passes occurring at different processing layers.
- Incomplete validation of resolved filesystem paths before FastCGI execution.
- Absence of strict enforcement ensuring
.phpextension checks after normalization.
When Unicode characters were interpreted differently before and after decoding, the effective execution target changed.
Exploitation Scenario
The vulnerability could be exploited remotely without authentication.
A realistic attack chain would involve:
- Uploading a malicious PHP payload disguised as a non-executable file (e.g.,
.jpg). - Accessing the file using a Unicode-encoded slash or separator.
- Triggering FastCGI execution after path re-interpretation.
Example payload (for educational testing only):
/uploads/avatar.jpg%EF%BC%8Findex.php
Or encoded traversal variant:
/public%2ephp%EF%BC%8F..%EF%BC%8Fuploads%EF%BC%8Fshell.php
Because normalization occurred inconsistently, the final interpreted path differed from the initial routing decision.
Impact
If successfully exploited:
- Arbitrary PHP code execution could occur.
- Web shell installation would be possible.
- Lateral movement inside the network could follow.
- Sensitive configuration files could be accessed.
- Full server takeover could be achieved depending on PHP permissions.
If Caddy was running with elevated privileges or inside a container with mounted secrets, impact severity would increase significantly.
Proof-of-Concept (Educational)
A minimal PoC involved:
- Deploying Caddy with PHP-FPM enabled.
- Allowing file upload to
/uploads/. - Crafting request:
curl "https://target/uploads/image.jpg%EF%BC%8Fshell.php"
If execution occurred instead of static serving, vulnerability was confirmed.
This behavior should only be tested in isolated lab environments.
MITRE ATT&CK Mapping
| Tactic | Technique | ID |
|---|---|---|
| Initial Access | Exploit Public-Facing Application | T1190 |
| Execution | Command and Scripting Interpreter | T1059 |
| Persistence | Server Software Component | T1505.003 |
| Defense Evasion | Obfuscated/Encoded Files | T1027 |
Detection
Log Sources
- Caddy Access Logs (JSON format recommended)
- Caddy Error Logs
- PHP-FPM logs
- Web Application Firewall logs
- Endpoint process execution logs
- EDR telemetry (process spawn tracking)
Indicators of Compromise
- Encoded Unicode slash patterns (
%EF%BC%8F) - Multiple
%2eencoded dot sequences - PHP execution outside intended directories
- Unusual
.phpinvocation in upload paths - High entropy query strings targeting static directories
Detection Queries
1. Suspicious Unicode Path Usage (Generic SIEM Query)
index=web_logs
| where like(request_uri, "%EF%BC%8F%")
OR like(request_uri, "%uFF0F%")
OR match(request_uri, ".*%2e.*%EF%BC%8F.*")
2. Unexpected PHP Execution from Upload Directory
index=php_logs
| where script_filename LIKE "%/uploads/%"
| stats count by script_filename, client_ip
3. Access Log Anomaly Detection
index=caddy_access
| stats count by request_uri, status
| where match(request_uri, "%EF%BC%8F") AND status=200
4. Web Shell Indicators
index=filesystem_logs
| where file_path LIKE "%.php"
| search "eval(" OR "base64_decode(" OR "system("
Remediation
- Upgrade to the latest Caddy stable release immediately.
- Enforce strict path canonicalization before routing.
- Disable PHP execution in upload directories.
- Implement deny rules for Unicode-encoded slashes.
- Apply WAF filtering for encoded traversal patterns.
- Run periodic integrity scans on web directories.
Official Patch / Upgrade Link
https://github.com/caddyserver/caddy/releases
CVE-2026-27586 – mTLS Fail-Open Authentication Bypass
Vulnerability Summary
| Field | Details |
|---|---|
| CVE ID | CVE-2026-27586 |
| Vulnerability Type | Improper Certificate Validation |
| Impact | Authentication Bypass |
| CVSS Score | 8.6 (High) |
| Attack Vector | Network |
| Privileges Required | None |
| User Interaction | None |
| Severity | High |
| Exploitability | Moderate |
| Exploit Availability | Configuration-based exploitation confirmed |
Technical Description
In certain configurations, when mTLS was enabled but the Certificate Authority (CA) file was:
- Missing,
- Incorrectly referenced,
- Corrupted,
- Or unreadable due to permission errors,
Caddy did not always enforce a hard failure. Instead, TLS negotiation could continue without validating the client certificate.
This resulted in fail-open behavior.
Instead of denying access, the server processed the request without proper client authentication.
Root Cause
The issue was caused by:
- Insufficient validation during TLS initialization.
- Inadequate startup failure enforcement.
- Lack of strict verification that a CA bundle was successfully loaded.
- Silent fallback logic allowing connection continuation.
Exploitation Scenario
An attacker would simply:
- Connect to a supposedly protected endpoint.
- Provide no client certificate.
- Receive successful HTTP response.
Example validation test:
curl https://target/internal -k
If access succeeded without client certificate, configuration was vulnerable.
No payload was required. The vulnerability relied purely on misconfiguration behavior.
Impact
If exploited:
- Administrative panels could be exposed.
- Internal APIs could be accessed externally.
- Kubernetes dashboards or monitoring endpoints could be reached.
- Zero-trust enforcement would be bypassed.
- Sensitive internal services would be accessible without credentials.
MITRE ATT&CK Mapping
| Tactic | Technique | ID |
|---|---|---|
| Initial Access | Exploit Public-Facing Application | T1190 |
| Credential Access | Valid Accounts Abuse | T1078 |
| Privilege Escalation | Exploitation of Misconfiguration | T1068 |
Detection
Log Sources
- Caddy startup logs
- TLS handshake logs
- Reverse proxy logs
- Firewall ingress logs
- Network flow telemetry
Indicators of Misconfiguration or Abuse
- Successful HTTP 200 responses from protected endpoints without certificate metadata
- Absence of
tls_client_subjectin access logs - Startup warnings about CA loading
- External IP addresses accessing internal paths
Detection Queries
1. Successful Requests Without Client Certificate
index=caddy_access
| where mTLS_enabled=true
| where isnull(tls_client_subject)
| where status=200
2. CA Loading Failure at Startup
index=caddy_error
| search "failed to load CA" OR "no client CA configured"
3. External Access to Internal Endpoints
index=caddy_access
| where request_uri LIKE "%/admin%" OR request_uri LIKE "%/internal%"
| stats count by client_ip, status
Remediation
- Upgrade to the latest Caddy release.
- Ensure CA file exists and permissions are correct.
- Enforce startup failure if CA validation fails.
- Implement firewall rules restricting sensitive endpoints.
- Validate mTLS enforcement with controlled testing after deployment.
- Enable strict logging of TLS client certificate details.
Official Patch / Upgrade Link
https://github.com/caddyserver/caddy/releases
Security Hardening Recommendations
- Enable structured JSON logging.
- Restrict PHP execution paths explicitly.
- Implement file integrity monitoring.
- Use read-only container filesystem where possible.
- Restrict outbound network access from web servers.
- Validate TLS configuration during CI/CD deployment.
- Conduct periodic penetration testing in staging environments.
