Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-15282

CVE-2025-15282: urllib.request XSS Vulnerability

CVE-2025-15282 is an XSS flaw in urllib.request.DataHandler that allows header injection via newlines in data URL mediatypes. This article covers the technical details, affected versions, impact, and mitigation.

Published:

CVE-2025-15282 Overview

CVE-2025-15282 is an HTTP Response Splitting vulnerability affecting Python's urllib.request.DataHandler. User-controlled data URLs parsed by this handler allow attackers to inject HTTP headers through newlines embedded in the data URL mediatype. This vulnerability enables HTTP Response Splitting attacks, which can lead to cache poisoning, cross-site scripting (XSS), or other injection-based exploits against downstream systems processing the malformed responses.

Critical Impact

Attackers can inject arbitrary HTTP headers by embedding newline characters in data URL mediatypes, potentially enabling cache poisoning, session hijacking, or cross-site scripting attacks.

Affected Products

  • Python CPython (versions with vulnerable urllib.request.DataHandler)

Discovery Timeline

  • 2026-01-20 - CVE CVE-2025-15282 published to NVD
  • 2026-01-20 - Last updated in NVD database

Technical Details for CVE-2025-15282

Vulnerability Analysis

This vulnerability exists in Python's urllib.request.DataHandler module, which processes data URLs (URLs with the data: scheme). The vulnerability is classified under CWE-93 (Improper Neutralization of CRLF Sequences), commonly known as CRLF Injection or HTTP Response Splitting.

The core issue stems from insufficient input validation when parsing the mediatype portion of data URLs. When a data URL is processed, the handler splits the URL by : and , delimiters to extract the mediatype and data components. However, prior to the patch, no validation existed to prevent control characters (including newlines \n and carriage returns \r) from being present in the mediatype string.

An attacker who can control the data URL being processed can craft a malicious URL where the mediatype contains CRLF sequences (\r\n). These sequences are interpreted as header delimiters in HTTP, allowing the injection of arbitrary headers into the response.

Root Cause

The root cause is missing input sanitization in urllib.request.DataHandler. The data_open method failed to validate or reject control characters (bytes 0x00-0x1F and 0x7F) within the mediatype portion of data URLs before processing them. This allowed CRLF sequences to pass through and be interpreted as HTTP header boundaries by downstream components.

Attack Vector

The attack vector is network-based and requires an attacker to control or influence the data URL being parsed by a vulnerable Python application. Attack scenarios include:

  1. Web Applications: Applications that accept user-supplied URLs and fetch them using urllib.request may be exploited if they process attacker-controlled data URLs
  2. API Endpoints: Services that parse incoming data URLs from request parameters
  3. File Processing: Applications processing documents or configurations containing data URLs

A malicious data URL might look like:

data:text/html%0d%0aX-Injected-Header:%20malicious-value,<script>alert(1)</script>

The %0d%0a sequences decode to CRLF, injecting the X-Injected-Header into the response.

python
# Security patch in Lib/urllib/request.py - gh-143925: Reject control characters in data: URL mediatypes
         scheme, data = url.split(":",1)
         mediatype, data = data.split(",",1)
 
+        # Disallow control characters within mediatype.
+        if re.search(r"[\\x00-\\x1F\\x7F]", mediatype):
+            raise ValueError(
+                "Control characters not allowed in data: mediatype")
+
         # even base64 encoded data URLs might be quoted so unquote in any case:
         data = unquote_to_bytes(data)
         if mediatype.endswith(";base64"):

Source: GitHub Commit Security Fix

Detection Methods for CVE-2025-15282

Indicators of Compromise

  • HTTP requests or responses containing unexpected headers injected via data URL processing
  • Log entries showing data URLs with URL-encoded control characters (%0d, %0a, %00-%1F, %7F)
  • Anomalous cache behavior or cache poisoning incidents linked to data URL handling
  • Web application firewall alerts for CRLF injection patterns in URL parameters

Detection Strategies

  • Implement regex-based detection rules to identify control characters in data URL mediatypes before processing
  • Monitor application logs for ValueError exceptions with the message "Control characters not allowed in data: mediatype" (post-patch)
  • Deploy web application firewall rules to detect and block CRLF injection attempts in URL parameters
  • Use static analysis tools to identify code paths where user input flows into urllib.request data URL processing

Monitoring Recommendations

  • Enable verbose logging for urllib.request operations in production environments
  • Monitor network traffic for anomalous HTTP headers that may indicate successful injection
  • Implement content security policies to mitigate potential XSS resulting from successful exploitation
  • Review application dependencies for Python versions affected by this vulnerability

How to Mitigate CVE-2025-15282

Immediate Actions Required

  • Update Python to a patched version that includes commit f25509e78e8be6ea73c811ac2b8c928c28841b9f
  • Audit application code for usage of urllib.request with user-controlled data URLs
  • Implement input validation to reject data URLs containing control characters before passing to urllib.request
  • Review and harden any web application components that process user-supplied URLs

Patch Information

The Python security team has released a patch that adds validation to reject control characters within data URL mediatypes. The fix uses a regular expression to detect bytes in the range 0x00-0x1F and 0x7F, raising a ValueError if any are found.

For detailed information, refer to:

Workarounds

  • Implement application-level input validation to sanitize or reject data URLs containing control characters before processing
  • Use allowlists for acceptable mediatype values when processing data URLs
  • Consider disabling data URL processing entirely if not required by your application
  • Deploy web application firewall rules to block requests containing CRLF sequences in URL parameters
python
# Workaround: Validate data URLs before processing with urllib.request
import re

def validate_data_url(url):
    """Reject data URLs with control characters in mediatype."""
    if url.startswith('data:'):
        # Extract mediatype portion
        parts = url[5:].split(',', 1)
        if parts:
            mediatype = parts[0]
            # Check for control characters
            if re.search(r'[\\x00-\\x1F\\x7F]', mediatype):
                raise ValueError("Control characters not allowed in data: mediatype")
    return url

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.