CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-116694

CVE-2026-116694: Unbounded Memory Allocation and Denial of Service in OpenTelemetry Python Jaeger Propagator

Alon Barad
Alon Barad
Software Engineer

Oct 28, 2026·10 min read·3 visits

Executive Summary (TL;DR)

OpenTelemetry Python's opentelemetry-propagator-jaeger package prior to version 1.45.0 fails to enforce entry count or byte-length boundaries when parsing 'uberctx-' baggage headers. Remote attackers can send oversized or numerous baggage keys to exhaust CPU and memory resources, leading to denial of service. Version 1.45.0 resolves this by applying W3C Baggage limits (180 entries, 4,096 bytes per entry, and 8,192 bytes total) to both extraction and injection routines.

CVE-2026-116694 (GHSA-f5m9-jfrj-jjj7) is an unbounded resource allocation vulnerability (CWE-770) in the optional Jaeger propagator component (opentelemetry-propagator-jaeger) of the OpenTelemetry Python SDK prior to version 1.45.0. When extracting distributed tracing context from inbound carriers, JaegerPropagator.extract() processes all headers prefixed with 'uberctx-' without enforcing limits on entry count, per-entry byte size, or aggregate byte size. In environments where transport-level header constraints are absent, relaxed, or bypassed (such as non-HTTP message brokers, RPC frameworks, or web servers with elevated buffer configurations), an unauthenticated remote attacker can supply high-volume or oversized baggage headers to trigger excessive URL unquoting, short-lived immutable dictionary allocations, and CPU starvation.

Vulnerability Overview

OpenTelemetry Python provides distributed context propagation mechanisms that allow telemetry metadata—such as trace identifiers and application-defined key-value pairs known as baggage—to traverse process boundaries. Within this ecosystem, the optional opentelemetry-propagator-jaeger package implements the legacy Jaeger native propagation protocol (JaegerPropagator). While the default OpenTelemetry configuration uses W3C Trace Context and W3C Baggage formats, applications integrating with older Jaeger instrumentation or mixed microservice estates explicitly configure JaegerPropagator to extract and inject trace state.

In the Jaeger propagation specification, trace identifiers are carried in the uber-trace-id header, while baggage items are transmitted as separate carrier entries prefixed with uberctx- (for example, uberctx-user-id). Unlike the W3C Baggage specification, which mandates strict limits on the number of list members and total byte length, the historical Jaeger propagation format did not specify upper bounds on baggage volume. Consequently, prior to version 1.45.0, the JaegerPropagator implementation in opentelemetry-propagator-jaeger accepted and parsed arbitrary quantities of uberctx- entries of any length.

Classified under CWE-770 (Allocation of Resources Without Limits or Throttling), this flaw exposes services using JaegerPropagator to resource exhaustion. When an instrumented service processes an inbound carrier containing thousands of uberctx- keys or multi-megabyte values, the propagator performs unbounded string manipulation, URL percent-decoding, and repeated context dictionary copies. When front-end transport layers do not restrict metadata size, unauthenticated callers can leverage this behavior to degrade service availability through memory pressure and CPU saturation.

Root Cause Analysis

The root cause of CVE-2026-116694 resides in the _extract_baggage and inject methods of the JaegerPropagator class, located in propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py. During inbound context extraction, JaegerPropagator.extract() delegates baggage handling to _extract_baggage(), passing the caller-supplied carrier object and its associated Getter implementation.

In versions prior to 1.45.0, _extract_baggage() executed a list comprehension over the entire key space returned by getter.keys(carrier), filtering for any key beginning with self.BAGGAGE_PREFIX ("uberctx-"). This initial step forced full evaluation of all matching keys in the carrier without an upper limit. If a carrier contained 10,000 keys prefixed with uberctx-, the list comprehension allocated a 10,000-element list and proceeded to iterate over every entry sequentially.

Within the extraction loop, each header value was retrieved via getter.get(carrier, key) and passed directly to urllib.parse.unquote(value).strip(). Because no per-entry or cumulative byte limit existed, passing a multi-megabyte string forced the Python runtime to scan the entire string buffer, decode percent-encoded sequences, and allocate new string objects on the heap. This string processing occurred synchronously on the request-handling thread or event loop.

Compounding the string allocation overhead is the design of OpenTelemetry's runtime Context and baggage API in Python. For every extracted key-value pair, _extract_baggage() invoked baggage.set_baggage(key, value, context=context). Because OpenTelemetry Context objects are immutable mappings, every call to set_baggage() instantiates a new Context object and copies the existing baggage dictionary to append the single new key. Processing $N$ baggage keys therefore results in $O(N^2)$ dictionary key copies and $N$ distinct heap allocations, amplifying garbage collection pressure. Furthermore, on outbound requests, JaegerPropagator.inject() iterated over all entries in the in-process baggage map without bounds, propagating oversized context state to downstream services.

Code Analysis

The vulnerability was remediated in Pull Request #5556 (commit 65c4eeb87cd3815dc795d3b5485e9ea0d5affcc7). Prior to this commit, the baggage extraction and injection routines in opentelemetry/propagators/jaeger/__init__.py contained no cardinality or byte-size checks:

# VULNERABLE CODE (Prior to 1.45.0)
def inject(
    self,
    carrier: CarrierT,
    context: typing.Optional[Context] = None,
    setter: Setter[CarrierT] = default_setter,
) -> None:
    # ... [trace context injection omitted] ...
    baggage_entries = baggage.get_all(context=context)
    if not baggage_entries:
        return
    # Unbounded iteration over all in-process baggage entries
    for key, value in baggage_entries.items():
        baggage_key = self.BAGGAGE_PREFIX + key
        setter.set(carrier, baggage_key, urllib.parse.quote(str(value)))
 
def _extract_baggage(
    self,
    getter: Getter[CarrierT],
    carrier: CarrierT,
    context: Context,
) -> Context:
    # Materializes all matching keys without an entry limit
    baggage_keys = [key for key in getter.keys(carrier) if key.startswith(self.BAGGAGE_PREFIX)]
    for key in baggage_keys:
        value = _extract_first_element(getter.get(carrier, key))
        if value is None:
            continue
        # Unbounded unquoting and O(N^2) immutable context re-allocation
        context = baggage.set_baggage(
            key.replace(self.BAGGAGE_PREFIX, ""),
            urllib.parse.unquote(value).strip(),
            context=context,
        )
    return context

To bound resource consumption, the patch adopts the structural limits defined by the W3C Baggage specification—already enforced by OpenTelemetry's core W3CBaggagePropagator—and applies them to JaegerPropagator. Specifically, the class defines MAX_BAGGAGE_ENTRIES = 180, MAX_BAGGAGE_ENTRY_BYTES = 4096, and MAX_BAGGAGE_TOTAL_BYTES = 8192.

# PATCHED CODE (Version 1.45.0+)
class JaegerPropagator(TextMapPropagator):
    TRACE_ID_KEY = "uber-trace-id"
    BAGGAGE_PREFIX = "uberctx-"
    DEBUG_FLAG = 0x02
    MAX_BAGGAGE_ENTRIES = 180
    MAX_BAGGAGE_ENTRY_BYTES = 4096
    MAX_BAGGAGE_TOTAL_BYTES = 8192
 
    def _extract_baggage(
        self,
        getter: Getter[CarrierT],
        carrier: CarrierT,
        context: Context,
    ) -> Context:
        # Generator expression paired with itertools.islice caps candidate inspection
        # at 180 keys, preventing CPU exhaustion from thousands of rejected keys.
        candidates = itertools.islice(
            (key for key in getter.keys(carrier) if key.startswith(self.BAGGAGE_PREFIX)),
            self.MAX_BAGGAGE_ENTRIES,
        )
        pairs = []
        for key in candidates:
            value = _extract_first_element(getter.get(carrier, key))
            if value is not None:
                pairs.append((key.replace(self.BAGGAGE_PREFIX, ""), value))
 
        # Filter pairs by per-entry and cumulative byte budgets before unquoting
        for baggage_key, value in _limit_baggage_bytes(
            pairs, self.MAX_BAGGAGE_ENTRY_BYTES, self.MAX_BAGGAGE_TOTAL_BYTES
        ):
            context = baggage.set_baggage(
                baggage_key,
                urllib.parse.unquote(value).strip(),
                context=context,
            )
        return context
 
    def _inject_baggage(
        self,
        setter: Setter[CarrierT],
        carrier: CarrierT,
        baggage_entries: collections.abc.Mapping[str, object],
    ) -> None:
        candidates = itertools.islice(baggage_entries.items(), self.MAX_BAGGAGE_ENTRIES)
        pairs = [(key, urllib.parse.quote(str(value))) for key, value in candidates]
 
        for key, encoded_value in _limit_baggage_bytes(
            pairs, self.MAX_BAGGAGE_ENTRY_BYTES, self.MAX_BAGGAGE_TOTAL_BYTES
        ):
            setter.set(carrier, self.BAGGAGE_PREFIX + key, encoded_value)
 
def _limit_baggage_bytes(
    pairs: collections.abc.Iterable[tuple[str, str]],
    max_entry_bytes: int,
    max_total_bytes: int,
) -> collections.abc.Iterator[tuple[str, str]]:
    total_bytes = 0
    accepted = 0
    for key, value in pairs:
        # Measure UTF-8 encoded byte length, plus 1 byte for the '=' delimiter
        entry_bytes = len(key.encode()) + len(value.encode()) + 1
        if entry_bytes > max_entry_bytes:
            continue
        # Account for 1-byte ',' separator between multiple baggage items
        separator_bytes = 1 if accepted > 0 else 0
        if total_bytes + separator_bytes + entry_bytes > max_total_bytes:
            continue
        yield key, value
        total_bytes += separator_bytes + entry_bytes
        accepted += 1

The patch addresses several subtle edge cases to ensure fix completeness:

  1. Candidate Inspection Limiting: _extract_baggage() replaces the list comprehension with a generator expression wrapped in itertools.islice(..., self.MAX_BAGGAGE_ENTRIES). Crucially, this bounds the number of candidates inspected rather than the number of valid entries retained. If the limit only counted retained entries, an attacker could send 50,000 oversized entries (each exceeding 4,096 bytes); all 50,000 would be rejected by the byte filter, forcing the loop to inspect and encode-check all 50,000 items.
  2. Pre-Unquote Byte Validation: _limit_baggage_bytes() evaluates len(key.encode()) + len(value.encode()) + 1 before calling urllib.parse.unquote(value).strip() or baggage.set_baggage(). Oversized values are discarded prior to URL decoding and context dictionary copying.
  3. UTF-8 Byte Accounting: Measuring len(key.encode()) rather than len(key) guarantees that multi-byte UTF-8 characters cannot exceed the 4,096-byte or 8,192-byte memory budgets.

Exploitation and Attack Scenarios

Exploiting CVE-2026-116694 requires two primary conditions: the target Python service must explicitly configure JaegerPropagator (via set_global_textmap(JaegerPropagator()) or instrumentation-specific propagator overrides, or via the OTEL_PROPAGATORS=jaeger environment variable), and the underlying transport layer must deliver oversized or high-count metadata fields to the application's TextMapGetter.

In standard HTTP deployments, web servers and reverse proxies enforce default header constraints that restrict the payload size reaching the Python WSGI or ASGI worker. For example, Gunicorn defaults to limit_request_fields = 100 and limit_request_field_size = 8190, while Uvicorn's h11 parser enforces a 16,384-byte incomplete event buffer limit. Under these default configurations, HTTP frontends block excessively large requests before JaegerPropagator.extract() is invoked.

However, practical exploitation becomes viable across several common architectural patterns where transport limits are relaxed or absent:

  • Elevated HTTP Proxy/Server Buffers: Services configured to accept large cookies, JWTs, or custom headers often raise Gunicorn's limit_request_field_size (or set it to 0 for unlimited) and increase Nginx's large_client_header_buffers.
  • Non-HTTP Message Brokers and Task Queues: When OpenTelemetry instruments asynchronous consumers (such as Kafka, RabbitMQ, or Celery workers), trace context and baggage are extracted from message headers or payload dictionaries using a TextMapGetter. Message brokers typically permit multi-megabyte message headers or thousands of dictionary keys without HTTP-style field limits.
  • Custom TextMapGetter Implementations: Applications extracting context from WebSocket frames, database records, or custom RPC protocols pass raw Python dictionaries directly to JaegerPropagator.extract().

The unit test suite committed alongside the patch in test_jaeger_propagator.py demonstrates the mechanics of triggering these boundary conditions:

# 1. High-cardinality key flood (exceeding 180 entries)
def test_extract_enforces_max_baggage_entries(self):
    old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id}
    for index in range(200):
        old_carrier[f"uberctx-k{index}"] = f"v{index}"
    # Unpatched versions extract all 200 items, performing 200 immutable Context copies.
    # Patched versions cap extraction at 180 entries.
    extracted = FORMAT.extract(old_carrier)[_BAGGAGE_KEY]
    self.assertEqual(FORMAT.MAX_BAGGAGE_ENTRIES, len(extracted))
 
# 2. Oversized single entry (exceeding 4,096 bytes)
def test_extract_drops_oversized_baggage_entry(self):
    old_carrier = {
        FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id,
        "uberctx-ok": "value",
        "uberctx-big": "x" * 5000,
    }
    # Unpatched versions unquote and store the 5,000-byte payload.
    # Patched versions drop "uberctx-big" prior to unquoting.
    context = FORMAT.extract(old_carrier)
    self.assertDictEqual({"ok": "value"}, context[_BAGGAGE_KEY])
 
# 3. Candidate inspection flood (1,000 oversized keys)
def test_extract_stops_inspecting_after_the_candidate_limit(self):
    old_carrier = {FORMAT.TRACE_ID_KEY: self.serialized_uber_trace_id}
    for index in range(1000):
        old_carrier[f"uberctx-k{index}"] = "x" * 5000
    # Unpatched versions inspect, unquote, and copy all 1,000 keys (5 MB total).
    # Patched versions halt getter evaluation after 180 candidates.

Impact Assessment

CVE-2026-116694 is assigned a CVSS v4.0 base score of 6.3 (Medium) with the vector CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N. The Attack Vector is Network (AV:N), Attack Complexity is Low (AC:L), and neither privileges (PR:N) nor user interaction (UI:N) are required. Attack Requirements are marked as Present (AT:P) because exploitation depends on both the explicit configuration of the non-default JaegerPropagator and a transport path that permits large or high-count metadata headers.

The security impact is confined strictly to system availability (VA:L), with no impact to confidentiality (VC:N) or integrity (VI:N). In Python applications—particularly single-threaded asynchronous event loops (such as asyncio with FastAPI or aiohttp) or pre-fork worker models with limited worker counts—CPU time spent synchronously iterating over thousands of keys, decoding percent-encoded strings, and copying dictionaries blocks the handling of concurrent requests.

Additionally, if an unpatched service extracts a high volume of uberctx- baggage items into its active Context and subsequently performs fan-out RPC or HTTP requests to downstream microservices using JaegerPropagator.inject(), the service will serialize and transmit all accumulated uberctx- headers on every outbound call. This behavior causes downstream amplification, multiplying memory allocation and network serialization overhead across internal service meshes or causes outbound requests to fail when downstream servers reject the oversized headers.

Remediation and Mitigation

The primary remediation is to upgrade opentelemetry-propagator-jaeger (and synchronized opentelemetry-python core packages) to version 1.45.0 or later. Version 1.45.0 enforces the 180-entry, 4,096-byte per-entry, and 8,192-byte total boundaries across both extract() and inject() methods without requiring configuration changes.

pip install --upgrade "opentelemetry-propagator-jaeger>=1.45.0"

> [!NOTE] > In 1.45.0+, baggage entries exceeding 4,096 bytes, entries that would push the cumulative size beyond 8,192 bytes, or candidates beyond the first 180 uberctx- keys are silently dropped during extraction and injection. Applications that legitimately rely on propagating payloads larger than 8 KB via Jaeger baggage must refactor their architecture, as distributed tracing headers are not designed for bulk data transport.

For deployments where immediate package upgrades are not possible, operators should implement the following compensating controls:

  1. Migrate to W3C Propagators: Unless legacy Jaeger compatibility is strictly required, remove jaeger from the OTEL_PROPAGATORS environment variable or code configuration and use the default tracecontext,baggage (W3C Trace Context and W3C Baggage) propagators, which already enforce strict specification limits.
  2. Enforce Strict Reverse Proxy and Server Header Limits: Verify that edge proxies (Nginx, Envoy, AWS ALB) and Python application servers (Gunicorn, Uvicorn) enforce strict upper bounds on header count and size. In Nginx, keep large_client_header_buffers 4 8k; or lower; in Gunicorn, ensure limit_request_fields <= 100 and limit_request_field_size <= 8190.
  3. Filter Custom Carriers: For non-HTTP consumers (Kafka, RabbitMQ, Celery, or custom RPC protocols) using custom TextMapGetter classes, implement a wrapper around getter.keys() and getter.get() that truncates uberctx- keys at 180 entries and drops values exceeding 4,096 bytes before invoking JaegerPropagator.extract().

Official Patches

OpenTelemetryGitHub Security Advisory GHSA-f5m9-jfrj-jjj7
OpenTelemetryGitHub Pull Request #5556 enforcing baggage limits in JaegerPropagator
OpenTelemetryOfficial fix commit in open-telemetry/opentelemetry-python
OpenTelemetryOpenTelemetry Python v1.45.0 Release

Fix Analysis (1)

Technical Appendix

CVSS Score
6.3/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Affected Systems

opentelemetry-propagator-jaeger (PyPI)open-telemetry/opentelemetry-python

Affected Versions Detail

Product
Affected Versions
Fixed Version
opentelemetry-propagator-jaeger
OpenTelemetry
< 1.45.01.45.0
AttributeDetail
CVE / Advisory IDCVE-2026-116694 / GHSA-f5m9-jfrj-jjj7
Affected Packageopentelemetry-propagator-jaeger (< 1.45.0)
Weakness ClassCWE-770 (Allocation of Resources Without Limits or Throttling)
CVSS v4.0 Score6.3 Medium (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N)
Attack VectorNetwork via inbound 'uberctx-*' carrier headers/metadata
Security ImpactDenial of Service via CPU exhaustion and repeated heap allocations
Exploit StatusUnit test reproduction in official repository; no wild exploitation reported
Patched Version1.45.0 (Enforces 180 entries, 4,096B/entry, 8,192B total)

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-770
Allocation of Resources Without Limits or Throttling

The software allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.

Vulnerability Timeline

Development cycle for OpenTelemetry Python 1.45.0.dev initiated (PR #5423)
2026-07-16
Patch enforcing W3C baggage limits in JaegerPropagator merged via PR #5556 (commit 65c4eeb87cd3815dc795d3b5485e9ea0d5affcc7)
2026-08-28
CVE-2026-116694 and GitHub Security Advisory GHSA-f5m9-jfrj-jjj7 officially published
2026-10-27

References & Sources

  • [1]GitHub Security Advisory: GHSA-f5m9-jfrj-jjj7
  • [2]GitHub Pull Request #5556: Enforce baggage limits on extract
  • [3]Fix Commit 65c4eeb87cd3815dc795d3b5485e9ea0d5affcc7
  • [4]OpenTelemetry Python Release v1.45.0
  • [5]CVE.org Record: CVE-2026-116694
  • [6]OpenTelemetry Python Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•43 minutes ago•CVE-2026-116686
6.5

CVE-2026-116686: Server-Side Request Forgery and Synchronous Denial of Service in Model Context Protocol Python SDK

CVE-2026-116686 is a Server-Side Request Forgery (SSRF) and Denial of Service (DoS) vulnerability in the official Model Context Protocol (MCP) Python SDK (mcp package on PyPI). When an MCP client validates structured tool execution results against a server-provided outputSchema, the SDK invokes the Python jsonschema library with its default URI resolution configuration. An untrusted or compromised MCP server can supply an outputSchema containing external $ref directives (using http://, https://, or file:// schemes), forcing the client process to synchronously fetch internal network resources, read local files, or block the main event loop indefinitely.

Amit Schendel
Amit Schendel
1 views•10 min read
•about 2 hours ago•CVE-2026-116685
5.9

CVE-2026-116685: Cross-Origin Redirect Credential and Request Payload Disclosure in MCP Python SDK

CVE-2026-116685 (GHSA-5h93-6whr-6q8j) is a sensitive information disclosure vulnerability in the official Model Context Protocol (MCP) Python SDK (`mcp` on PyPI). In versions 1.8.0 through 1.29.1 and 2.0.0 through 2.1.1, the SDK's HTTP-based client transports—including Streamable HTTP, Server-Sent Events (SSE), and OAuth client flows—unconditionally enable automatic HTTP redirect following (`follow_redirects=True`) across origin boundaries. When a configured endpoint returns a redirect to an external origin, the HTTP client forwards caller-supplied custom authentication headers (such as `X-API-Key`) and, in the case of HTTP 307 or 308 responses, replays the full POST request body containing JSON-RPC payloads or OAuth parameters to the untrusted destination.

Alon Barad
Alon Barad
4 views•11 min read
•about 4 hours ago•CVE-2026-116684
6.8

CVE-2026-116684: Resource-Confusion Authorization Bypass in Model Context Protocol Python SDK

CVE-2026-116684 is an incorrect authorization vulnerability (CWE-863) in the Model Context Protocol (MCP) Python SDK (`modelcontextprotocol/python-sdk`). The server-side bearer authentication middleware (`BearerAuthBackend`) verifies token cryptographic signatures and expiration timestamps via `TokenVerifier`, but fails to verify that the token's audience (`aud` claim or RFC 8707 resource indicator) matches the receiving MCP server's configured `resource_server_url`. In multi-service environments sharing a single OAuth 2.0 Authorization Server, an attacker possessing a valid token for an unrelated service can replay it against the MCP server to gain unauthorized access to protected tools, resources, and prompts.

Amit Schendel
Amit Schendel
5 views•9 min read
•about 5 hours ago•CVE-2026-116675
8.5

CVE-2026-116675: Stored Cross-Site Scripting in TinyMCE Media Plugin via Pre-Sanitization DOM Instantiation

CVE-2026-116675 is a stored Cross-Site Scripting (XSS) vulnerability in the TinyMCE rich text editor affecting versions 7.9.3 and 8.5.1 through 8.9.2. The flaw resides in the media plugin's serialization logic, where placeholder elements configured with the data-mce-object attribute are converted into real DOM elements using the active window's document context prior to sanitization. When an attacker supplies a media element with an invalid source attribute alongside an inline event handler attribute such as data-mce-p-onerror, the browser resolves the resource and executes the malicious JavaScript before the sanitizer can strip the dangerous attributes.

Alon Barad
Alon Barad
5 views•10 min read
•about 6 hours ago•CVE-2026-116693
8.7

CVE-2026-116693: Regular Expression Denial of Service in Datadog Node.js Tracer (dd-trace)

CVE-2026-116693 is a high-severity Regular Expression Denial of Service (ReDoS) vulnerability affecting the official Datadog Application Performance Monitoring (APM) client library for Node.js, dd-trace. The defect resides in the default regular expression defined by the DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP configuration parameter, which is used to sanitize incoming and outgoing HTTP URL query strings prior to recording trace span metadata. Due to overlapping sub-patterns and unanchored repetition blocks in the JSON Web Token (JWT) and URL-encoded string matching branches, the V8 JavaScript engine's regular expression subsystem (Irregexp) can be forced into catastrophic or high-degree polynomial backtracking. Because regular expression replacement occurs synchronously on the primary Node.js event loop, an unauthenticated remote attacker can send crafted HTTP requests with malicious query strings to consume 100% of the process CPU core, stalling concurrent request processing and rendering the application unavailable.

Alon Barad
Alon Barad
5 views•10 min read
•about 7 hours ago•CVE-2026-116692
9.8

CVE-2026-116692: Remote Code Execution in MLflow via Third-Party Scorer Deserialization

CVE-2026-116692 (GHSA-26p8-2jq9-3vq9) is a remote code execution vulnerability in MLflow affecting versions 3.12.0rc0 prior to 3.17.0. The flaw stems from an overly permissive module prefix check during the deserialization of third-party GenAI evaluation scorers in mlflow/genai/scorers/base.py. By setting an experiment's artifact root to a local package directory within the Python module search path and uploading a crafted Python file as a run artifact, an attacker can invoke the /ajax-api/3.0/mlflow/scorer/invoke endpoint to dynamically import and execute arbitrary code on the MLflow tracking server.

Amit Schendel
Amit Schendel
9 views•9 min read