CVE-2026-24853 : Caido has an insufficient patch for DNS rebind leading to RCE
Chained Caido Vulnerability with XSS, results in complete RCE

Description
Caido is a web security auditing toolkit. Prior to 0.55.0, Caido blocks non whitelisted domains to reach out through the 8080 port, and shows Host/IP is not allowed to connect to Caido on all endpoints. But this is bypassable by injecting a X-Forwarded-Host: 127.0.0.1:8080 header. This vulnerability is fixed in 0.55.0.
Severity
NIST: NVD - Base Score: 9.8 CRITICAL
CNA: GitHub, Inc. - Base Score: 8.1 HIGH

Exploitation
Introduction
Most local running apps which happen to have a web server, tend be to unauthenticated. The only savior preventing XSS on such apps is the browser’s Cross Origin Policy.
Cross Origin Policy blocks a domain from accessing fetch response of another domain. It also forces a preflight response for non-simple requests, blocking blind csrf as well.
Functionality
Caido’s core functionally is wrapped around a webserver, which runs on port 23232 by default. It also allows guest login functionality on localhost.
It uses graphql, so we can login as guest by using this query -
mutation LoginAsGuest {
loginAsGuest {
token {
accessToken
refreshToken
expiresAt
scopes
}
error {
__typename
code
}
}
}
Next, once an unauthenticated user logs in, he can create a new workflow, and set the target of a node to "exec", we can run arbitrary commands on the system with no restrictions.
{
"alias": "shell",
"definition_id": "caido/http-shell-cmd",
"id": 2,
"inputs": [
{ "alias": "shell", "value": { "data": "cmd", "kind": "string" } },
{ "alias": "timeout", "value": { "data": 2000, "kind": "integer" } },
{ "alias": "code", "value": { "data": "calc.exe", "kind": "string" } }
]
}
The above sets node trigger to open calc.exe, and sent to createWorkflow mutation. We can use a trigger like on_request or manually trigger the workflow from another request.
Exploit Chain
Now how do we login and send this payload with CORS? DNS rebinding is used to bypass CORS. We map a.com to bind to our IP, serve a webpage on a.com:23232, and change DNS of a.com to 127.0.0.1. Now every fetch request we make will resolve to locally running Caido’s instance. CORS won’t be effective since we never changed origin. So we can technically send the above payloads and get RCE.
The browsers cache DNS for 60s. To achieve split second DNS rebinding in chrome, we have to use multiple A records, 1 pointing to our server, and 1 pointing to 127.0.0.1. As soon as we get a request on our server, we will it, so that next request falls back to 127.0.0.1.
But DNS rebinding was already patched! In CVE-2025-49004, DNS rebinding was patched and a hostname check was introduced. If the host isn’t localhost or 127.0.0.1, Caido won’t allow any access including graphql. In browsers, its impossible to forge a hostname in a request.
A quick bypass
The team forgot that their server allowed X-Forwarded-Host override. This header is allowed in browsers. An internal handler saw X-Forwarded-Host: 127.0.0.1, and updated the “Host” header using it. This bypassed the blocked hostname check, and DNS rebinding became viable again!
The chrome has introduced PNA checks, blocking pages loaded from outer IPs to send requests to local IPs. To bypass it, just an additional perm is needed to open new tab. A detailed writeup on PNA bypass in future.