VAITP Dataset

← Back to the dataset

CVE-2025-3264

ReDoS in Hugging Face Transformers' get_imports() can cause Denial of Service.

  • CVSS 5.3
  • CWE-1333
  • Resource Management
  • Remote

A Regular Expression Denial of Service (ReDoS) vulnerability was discovered in the Hugging Face Transformers library, specifically in the `get_imports()` function within `dynamic_module_utils.py`. This vulnerability affects versions 4.49.0 and is fixed in version 4.51.0. The issue arises from a regular expression pattern `\s*try\s*:.*?except.*?:` used to filter out try/except blocks from Python code, which can be exploited to cause excessive CPU consumption through crafted input strings due to catastrophic backtracking. This vulnerability can lead to remote code loading disruption, resource exhaustion in model serving, supply chain attack vectors, and development pipeline disruption.

CVSS base score
5.3
Published
2025-07-07
OWASP
A04 Insecure Design
Orthogonal defect classification
Algorithm
Code defect classification
Incorrect Algorithm
Category
Resource Management
Subcategory
Resource Exhaustion
Accessibility scope
Remote
Impact
Denial of Service (DoS)
Affected component
Hugging Face
Fixed by upgrading
Yes

Solution

Upgrade Hugging Face Transformers to version 4.51.0 or later.

Vulnerable code sample

import re
import time

def demonstrate_vulnerability(code: str):
    """
    A function that uses the ReDoS-vulnerable regular expression found in
    Hugging Face Transformers version 4.49.0 in dynamic_module_utils.py.
    The vulnerability is in the _re_try_except pattern.
    """
    # Vulnerable Regex from the `get_imports` function
    _re_try_except = re.compile(r"\s*try\s*:.*?except.*?:", re.DOTALL)
    
    # The `sub` operation on a crafted string will trigger catastrophic backtracking
    return _re_try_except.sub("", code)

# A crafted input string designed to exploit the vulnerability.
# The string starts with 'try:' and is followed by a sequence of characters
# that will cause the `.*?` to backtrack excessively when the pattern fails
# to find a matching 'except...:'.
# A length of 25-30 is often enough to cause a noticeable hang.
payload_length = 28
crafted_input = "try:" + " " * payload_length

print(f"Attempting to process a crafted string of length {len(crafted_input)}.")
print("The execution will hang or take a very long time due to the ReDoS vulnerability.")
print("...")

start_time = time.time()

# This call will trigger the vulnerability, causing high CPU usage and a long delay.
demonstrate_vulnerability(crafted_input)

end_time = time.time()
execution_time = end_time - start_time

print(f"Execution finished after {execution_time:.4f} seconds.")

Patched code sample

import re
import time

# This POC is based on the vulnerability description for CVE-2025-3264 (a placeholder for the real CVE-2024-3264).
# The vulnerable regex pattern can cause catastrophic backtracking with a crafted input,
# leading to a Denial of Service (DoS) due to high CPU usage.

def get_imports_vulnerable(code: str) -> str:
    """
    Simulates the vulnerable function from transformers<=4.49.0.
    The regex `.*?` can lead to catastrophic backtracking because it's too general
    and is used between two other patterns.
    """
    # VULNERABLE PATTERN
    vulnerable_pattern = r"\s*try\s*:.*?except.*?:"
    try:
        # The re.sub call is where the ReDoS occurs.
        return re.sub(vulnerable_pattern, "", code, flags=re.DOTALL)
    except re.error as e:
        # The regex engine may time out on very long inputs
        return f"Regex error: {e}"

def get_imports_fixed(code: str) -> str:
    """
    Simulates the fixed function from transformers>=4.51.0.
    The fix replaces the general `.*?` with a more specific `[^:]*?`, which means
    "match any character except a colon, non-greedily". This prevents the regex
    engine from backtracking across multiple `except` blocks or deeply nested structures,
    thus mitigating the ReDoS vulnerability.
    """
    # FIXED PATTERN
    # By excluding the colon ':', the pattern becomes non-backtracking for the intended use case.
    fixed_pattern = r"\s*try\s*:[^:]*?except[^:]*?:"
    return re.sub(fixed_pattern, "", code, flags=re.DOTALL)

if __name__ == "__main__":
    # A crafted string that triggers catastrophic backtracking in the vulnerable regex.
    # It starts with "try:", has a long sequence of characters that are not "except",
    # and ends with "except" but no final colon. The regex engine will try every
    # possible partition of the long string, leading to exponential complexity.
    print("Crafting malicious input string...")
    # A length of >25 is typically enough to show significant slowdown.
    malicious_part = "a" * 28
    evil_string = f"try:{malicious_part}except"
    print(f"Malicious string length: {len(evil_string)}\n")

    # --- Demonstrate Vulnerability ---
    print("Testing VULNERABLE function (transformers<=4.49.0)...")
    print("This may take a long time or hang indefinitely. Press CTRL+C to stop.")
    start_time_vuln = time.monotonic()
    try:
        get_imports_vulnerable(evil_string)
    except KeyboardInterrupt:
        print("\nExecution interrupted by user.")
    end_time_vuln = time.monotonic()
    print(f"Vulnerable function took: {end_time_vuln - start_time_vuln:.4f} seconds.\n")

    # --- Demonstrate Fix ---
    print("Testing FIXED function (transformers>=4.51.0)...")
    start_time_fixed = time.monotonic()
    get_imports_fixed(evil_string)
    end_time_fixed = time.monotonic()
    print(f"Fixed function took: {end_time_fixed - start_time_fixed:.4f} seconds.")

    # --- Conclusion ---
    if (end_time_vuln - start_time_vuln) > 1:
         print("\nDemonstration successful: The fixed function is orders of magnitude faster.")
    else:
         print("\nDemonstration note: Increase the multiplier in 'malicious_part' if the slowdown is not obvious on your machine.")

Payload

"try:" + " except" * 50000

Cite this entry

@misc{vaitp:cve20253264,
  title        = {{ReDoS in Hugging Face Transformers' get_imports() can cause Denial of Service.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2025},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2025-3264},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-3264/}}
}
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 ::