Listen to this Post
The vulnerability resides in Caddy’s FastCGI transport function `splitPos()` inside modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go. It misuses `golang.org/x/text/search` with `search.IgnoreCase` when the request path contains a non‑ASCII byte. Two distinct flaws allow an attacker to trick Caddy into treating a non‑.php file as a script, leading to remote code execution if the attacker can place content into a file served via FastCGI (e.g., uploads).
Flaw 1 – Stale `match` after fallback
When the inner `for j` loop encounters a byte c >= utf8.RuneSelf, it calls splitSearchNonASCII.IndexString(). If that returns -1, the loop `break`s without setting match = false. The outer code then sees `match` still `true` and returns i + splitLen, incorrectly treating the file as a script even though no valid extension matched.
Flaw 2 – Unicode equivalence folding
`search.New(language.Und, search.IgnoreCase)` performs full Unicode case‑folding and compatibility decomposition. Many non‑ASCII characters (e.g., fullwidth dot ., mathematical bold 𝗽, etc.) fold onto ASCII ., p, h, p. Thus a path containing `.php` or `.𝗽𝗵𝗽` is reported as .php, bypassing the intended ASCII‑only extension check.
Both flaws share the same root cause: invoking a Unicode‑aware search on an ASCII‑only, lower‑cased `SplitPath` entry while the path contains non‑ASCII bytes. Because `Provision()` guarantees split entries are ASCII, any non‑ASCII byte in the path can never be part of a legitimate match – yet the fallback incorrectly assumes it can.
dailycve form:
Platform: Caddy
Version: < fixed (commit 4ddad83c)
Vulnerability: RCE via split_path bypass
Severity: High (8.1)
date: 2026-05-18
Prediction: Patch already released (2026-05-17)
What Undercode Say:
Test for flaw 1 – file with non‑ASCII byte .¡.txt curl -i --path-as-is "http://127.0.0.1:8080/poc-match-unset.%C2%A1.txt/trigger" Test for flaw 2 – Unicode lookalike .𝗽𝗵𝗽 curl -i --path-as-is "http://127.0.0.1:8080/poc-search-norm.%F0%9D%97%BD%F0%9D%97%B5%F0%9D%97%BD.anything/trigger" Check if a normal .txt file is NOT routed to PHP (should 404) curl -i --path-as-is "http://127.0.0.1:8080/poc-match-unset.txt/trigger"
How Exploit:
Place a file with a crafted name (e.g., `poc-match-unset.¡.txt` containing <?php system($_GET['cmd']); ?>) in a publicly writable directory. Send a request with the URL‑encoded non‑ASCII byte or Unicode lookalike sequence, appended with /trigger. Caddy’s `splitPos()` returns a position inside the non‑.php filename, causing FastCGI to execute it as PHP.
Protection from this CVE:
Update Caddy to commit `4ddad83c` or any release containing the patch. The fix removes the `golang.org/x/text/search` fallback entirely and treats any `byte >= utf8.RuneSelf` as a non‑match. As a workaround, avoid serving user‑uploaded files via FastCGI or use strict path validation at the web application level.
Impact:
Remote code execution (RCE) on the FastCGI upstream (e.g., PHP‑FPM). Precondition: attacker can upload or control a file whose name contains a non‑ASCII byte or Unicode lookalike of .php. Common in file upload endpoints, content stores, or package mirrors. CVSS 8.1 (High).
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

