VAITP Dataset

← Back to the dataset

CVE-2026-32722

Memray is vulnerable to XSS in HTML reports via command line arguments.

  • CVSS 6.1
  • CWE-79
  • Input Validation and Sanitization
  • Local

Memray is a memory profiler for Python. Prior to Memray 1.19.2, Memray rendered the command line of the tracked process directly into generated HTML reports without escaping. Because there was no escaping, attacker-controlled command line arguments were inserted as raw HTML into the generated report. This allowed JavaScript execution when a victim opened the generated report in a browser. Version 1.19.2 fixes the issue.

CVSS base score
6.1
Published
2026-03-18
OWASP
A03 Injection
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Cross-Site Scripting (XSS)
Accessibility scope
Local
Impact
Arbitrary Code Execution
Affected component
Memray
Fixed by upgrading
Yes

Solution

Upgrade Memray to version 1.19.2 or later.

Vulnerable code sample

import sys
import os

def generate_vulnerable_html_report(command_line_list, output_path):
    """
    This function simulates the behavior of Memray prior to version 1.19.2.
    It takes a list of command line arguments and embeds them directly
    into an HTML report without any form of escaping, creating a
    Cross-Site Scripting (XSS) vulnerability.
    """
    # The command line arguments are joined into a single string.
    command_line_str = " ".join(command_line_list)

    # The unescaped string is inserted directly into the HTML template.
    # An attacker can provide a command line argument like:
    # "<script>alert('XSS executed!');</script>"
    # This script tag will be rendered as raw HTML in the final report.
    html_template = f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Memray Report (Vulnerable Version)</title>
</head>
<body>
    <h1>Process Report</h1>
    <hr>
    <h2>Command</h2>
    <code>{command_line_str}</code>
    <hr>
    <h2>Memory Usage</h2>
    <p>... some memory data ...</p>
</body>
</html>
"""
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(html_template)

if __name__ == '__main__':
    # This simulates Memray capturing the command line of a tracked process.
    # The arguments passed to this script will be used in the report.
    # To trigger the vulnerability, run this script with a payload, e.g.:
    # python vulnerable_script.py an_argument "<script>alert('This is a PoC for CVE-2023-32722');</script>"
    captured_command_line = sys.argv
    
    report_filename = "vulnerable_report.html"
    
    # Generate the report using the vulnerable function.
    generate_vulnerable_html_report(captured_command_line, report_filename)

Patched code sample

import shlex
from html import escape
from typing import Dict, List


def generate_report_context_with_fix(metadata: Dict[str, any]) -> Dict[str, any]:
    """
    This function demonstrates the fix for the XSS vulnerability CVE-2024-32722
    in Memray.

    The vulnerability was caused by rendering raw command-line arguments into an
    HTML report. An attacker could provide a malicious string as a command-line
    argument, which would be executed as JavaScript when the report was viewed.

    The fix involves escaping the command-line string before it is embedded in
    the report. This function simulates that process.

    Args:
        metadata: A dictionary containing report metadata, including a
                  'command_line' key with a list of arguments.

    Returns:
        A dictionary of context data ready for safe HTML rendering.
    """
    command_line_args: List[str] = metadata.get("command_line", [])

    # VULNERABLE IMPLEMENTATION (for conceptual reference):
    #
    #   vulnerable_command_line = " ".join(command_line_args)
    #   context = {"command_line": vulnerable_command_line}
    #
    # If an argument was "<script>alert('XSS')</script>", the string would be
    # injected directly into the HTML, causing the script to execute.

    # FIXED IMPLEMENTATION:
    # The command-line arguments are joined, and then the entire string is
    # passed to `html.escape()`. This converts special HTML characters
    # (like '<', '>', '&') into their safe entity equivalents (e.g., '<',
    # '>', '&').
    safe_command_line = escape(" ".join(command_line_args))

    # The resulting context contains a string that is safe to be rendered
    # in an HTML document.
    return {
        "command_line": safe_command_line,
        "pid": metadata.get("pid"),
        # ... other metadata would be included here
    }


if __name__ == '__main__':
    # --- DEMONSTRATION ---

    # 1. Metadata with a malicious payload in the command line
    malicious_metadata = {
        "pid": 12345,
        "command_line": [
            "python",
            "my_app.py",
            "--user-input",
            "<script>alert('This script executes if not escaped!')</script>"
        ]
    }

    # 2. Generate the report context using the fixed function
    safe_context = generate_report_context_with_fix(malicious_metadata)

    # 3. Show the output. The malicious script is now harmless text.
    print("Original malicious argument: ", malicious_metadata["command_line"][-1])
    print("\nSafely escaped command line for HTML report:")
    print(safe_context["command_line"])

    # The output shows that '<script>' has been converted to '<script>',
    # which browsers will display as text instead of executing as code.
    #
    # EXPECTED OUTPUT:
    # python my_app.py --user-input <script>alert('This script executes if not escaped!')</script>

Payload

<script>alert('XSS')</script>

Cite this entry

@misc{vaitp:cve202632722,
  title        = {{Memray is vulnerable to XSS in HTML reports via command line arguments.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-32722},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-32722/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::