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-116691

CVE-2026-116691: Cleartext LLM Provider API Key Disclosure in MLflow CrewAI Autologging

Alon Barad
Alon Barad
Software Engineer

Oct 27, 2026·12 min read·2 visits

Executive Summary (TL;DR)

MLflow versions 2.19.0 to 3.16.x leak plaintext LLM API keys into OpenTelemetry trace attributes and span inputs when mlflow.crewai.autolog() is used with CrewAI agents configured with explicit API keys. Users should upgrade to MLflow 3.17.0 and rotate affected credentials.

CVE-2026-116691 (GHSA-j7qq-vr8c-xvw3) is a sensitive credential disclosure vulnerability in the MLflow platform affecting versions 2.19.0 through 3.16.x. When CrewAI autologging is enabled via mlflow.crewai.autolog(), the tracing instrumentation fails to sanitize nested CrewAI LLM objects before serializing them into OpenTelemetry trace spans. Consequently, plaintext LLM provider API keys are extracted from object dictionaries and string representations, then transmitted and stored in MLflow tracking servers or external OpenTelemetry Protocol (OTLP) telemetry backends.

Vulnerability Overview

MLflow is an open-source platform designed to manage the machine learning and artificial intelligence lifecycle, providing experiment tracking, model registry, and OpenTelemetry-compatible observability tracing. To instrument multi-agent applications built with the CrewAI framework, MLflow exposes the mlflow.crewai.autolog() module. This integration automatically hooks into key CrewAI lifecycle events—including agent execution, task execution, and crew kickoff—to capture inputs, outputs, execution duration, and component metadata as structured trace spans.

In MLflow versions starting from 2.19.0 and prior to 3.17.0, the CrewAI autologging module contains an information disclosure vulnerability classified under CWE-532 (Insertion of Sensitive Information into Log File), CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor), and CWE-312 (Cleartext Storage of Sensitive Information). When a CrewAI Agent or Crew is initialized with an LLM instance that holds an explicit API key (for example, LLM(model="gpt-4.1-mini", api_key="sk-proj-...")), the autologging hooks extract the internal state of these objects by iterating over their __dict__ attributes without recursively scrubbing nested credential fields.

During span creation, the unsanitized LLM instances are converted into string representations or expanded as raw dictionaries. Because CrewAI's LLM class retains the api_key parameter as a standard instance attribute, calling str() on the object or dumping its dictionary embeds the raw secret directly into the resulting telemetry payload. These spans are then automatically exported over the network to the configured MLflow tracking server or downstream OpenTelemetry Protocol (OTLP) collector.

The exposure occurs transparently during normal agent execution and requires no faulty logging logic by the application developer. Any user, service, or monitoring platform with read access to the MLflow trace UI, trace REST API, backing storage database, or remote observability platform can retrieve the plaintext LLM provider credentials.

Root Cause Analysis

The root cause of CVE-2026-116691 is an incomplete sanitization architecture in mlflow/crewai/autolog.py that failed to account for object composition and nested Pydantic models within CrewAI components. While the developers recognized the need to redact secrets in isolated contexts, the sanitization logic was applied inconsistently across two distinct serialization code paths: span attribute extraction and function input construction.

The first leakage path occurs in _get_agent_attributes(instance), which is invoked by _set_span_attributes() whenever an Agent instance is traced. This function iterates over instance.__dict__.items() to collect configuration metadata for the span. In vulnerable versions, the loop applied specialized handling only to the tools key (via _parse_tools()) and the embedder key (via _sanitize_value()). All other attributes on the Agent instance—specifically llm, function_calling_llm, agent_executor, and crew—bypassed _sanitize_value() entirely and were coerced directly via str(value). When Python evaluated str(agent.llm), the default object representation of the CrewAI LLM instance serialized all internal fields, outputting a string containing api_key='sk-proj-...'.

Notably, MLflow's dedicated extractor for standalone LLM calls, _get_llm_attributes(instance), already contained an explicit filter (elif key in ["callbacks", "api_key"]: continue) to prevent logging the api_key attribute on direct LLM spans. However, because _get_agent_attributes() serialized the Agent object's sub-components via string conversion rather than delegating nested LLM objects to _get_llm_attributes() or a recursive sanitizer, the protection was completely bypassed during agent-level tracing.

The second independent leakage path resides in _construct_full_inputs(func, *args, **kwargs), which captures the arguments passed to traced CrewAI methods and records them under the mlflow.spanInputs attribute. This function constructed a dictionary by expanding any argument possessing a __dict__ attribute (k: v.__dict__ if hasattr(v, "__dict__") else v) without invoking _sanitize_value() on the resulting structure. When methods such as Task.execute_sync or Agent.execute_task were executed, the Agent instance was passed as a function argument, causing its internal __dict__—and the nested LLM object containing the plaintext api_key—to be serialized directly into the span inputs.

Code Analysis

In vulnerable versions of MLflow (>= 2.19.0, < 3.17.0), the implementation of _get_agent_attributes(), _construct_full_inputs(), and _sanitize_value() in mlflow/crewai/autolog.py lacked recursive object traversal and comprehensive key matching. Below is the vulnerable code prior to the fix:

# Vulnerable implementation in mlflow/crewai/autolog.py
def _construct_full_inputs(func, *args, **kwargs):
    signature = inspect.signature(func)
    arguments = signature.bind_partial(*args, **kwargs).arguments
    if "self" in arguments:
        arguments.pop("self")
 
    # VULNERABILITY (Path 2): Expands object __dict__ without sanitization,
    # exposing nested LLM instances inside Agent arguments.
    return {
        k: v.__dict__ if hasattr(v, "__dict__") else v
        for k, v in arguments.items()
        if v is not None and _is_serializable(v)
    }
 
def _get_agent_attributes(instance):
    agent = {}
    for key, value in instance.__dict__.items():
        if key == "tools":
            value = _parse_tools(value)
        elif key == "embedder":
            value = _sanitize_value(value)
        if value is None:
            continue
        # VULNERABILITY (Path 1): Fields like 'llm', 'function_calling_llm', and
        # 'agent_executor' are not sanitized before calling str(value).
        agent[key] = str(value)
    return agent
 
def _sanitize_value(val):
    if val is None:
        return None
    sensitive_keys = ["api_key", "secret", "password", "token"]
    # VULNERABILITY: Only handles plain dicts and lists; ignores Pydantic models
    # and CrewAI LLM instances.
    if isinstance(val, dict):
        sanitized = {}
        for k, v in val.items():
            if any(sensitive in k.lower() for sensitive in sensitive_keys):
                continue
            sanitized[k] = _sanitize_value(v)
        return sanitized
    elif isinstance(val, list):
        return [_sanitize_value(item) for item in val]
    return val

Pull Request #25845 (commit 20927930d27f0072fcfeb7f024f24ad8c5e77c47) remediates the vulnerability by overhauling how span attributes, function inputs, and outputs are sanitized across mlflow/crewai/autolog.py. First, the patch introduces _SENSITIVE_KEY_PATTERN, a compiled regular expression that matches credential-related key names (api_key, secret, password, authorization, credential, and standalone or camelCase token/Token suffixes) while preserving benign configuration keys such as max_tokens, tokenizer, and token_usage.

# Patched implementation in mlflow/crewai/autolog.py
_SENSITIVE_KEY_PATTERN = re.compile(
    r"(?i:api_?key|secret|password|authorization|credential)"  # anywhere in the key
    r"|(?<![A-Za-z])(?i:token)$"  # snake_case / standalone `token`
    r"|(?<=[a-z])Token$"  # camelCase `accessToken`
)
 
def _set_sanitized_attribute(span: LiveSpan, key: str, value: Any):
    # Drop top-level attributes whose key name matches the sensitive pattern
    if _SENSITIVE_KEY_PATTERN.search(key):
        return
    value = _sanitize_value(value)
    span.set_attribute(key, str(value) if isinstance(value, list) else value)
 
def _get_agent_attributes(instance):
    agent = {}
    for key, value in instance.__dict__.items():
        if _SENSITIVE_KEY_PATTERN.search(key):
            continue
        if key == "tools":
            value = _parse_tools(value)
        # FIX: Sanitize all values (including nested LLM objects) BEFORE stringifying
        value = _sanitize_value(value)
        if value is None:
            continue
        agent[key] = str(value)
    return agent

Second, the patch replaces the naive _sanitize_value() implementation with a cycle-aware, fail-closed recursive sanitizer (_sanitize_value_impl). When encountering a CrewAI LLM instance (detected via _is_crewai_llm()), the sanitizer reduces the entire object to its model identifier string via _get_llm_summary(), preventing both str(llm) and dictionary dumps from exposing internal credentials. For other pydantic.BaseModel subclasses (such as Agent, Task, and Crew), the sanitizer recursively traverses val.__dict__ while tracking object memory addresses (id(val)) in an ancestors set to prevent infinite recursion on circular references (such as Agent.crew -> Crew.agents -> Agent).

def _sanitize_value(val):
    try:
        return _sanitize_value_impl(val, set())
    except Exception as e:
        _logger.debug("Failed to sanitize %s for span logging: %s", type(val).__name__, e)
        # Fail-closed: return placeholder on error rather than logging unsanitized data
        return f"<{type(val).__name__}: omitted, sanitization failed>"
 
def _sanitize_value_impl(val, ancestors: set[int]):
    if val is None or isinstance(val, (str, int, float, bool)):
        return val
    if id(val) in ancestors:
        return type(val).__name__
    ancestors.add(id(val))
    try:
        if isinstance(val, dict):
            return {
                k: _sanitize_value_impl(v, ancestors)
                for k, v in val.items()
                if not (isinstance(k, str) and _SENSITIVE_KEY_PATTERN.search(k))
            }
        if isinstance(val, (list, tuple, set)):
            sanitized = [_sanitize_value_impl(item, ancestors) for item in val]
            return tuple(sanitized) if isinstance(val, tuple) else sanitized
        if _is_crewai_llm(val):
            return _get_llm_summary(val)
        if isinstance(val, pydantic.BaseModel):
            return _sanitize_value_impl(val.__dict__, ancestors)
        return val
    finally:
        ancestors.discard(id(val))

The fix also wraps the return dictionary of _construct_full_inputs() and the outputs of patched_standalone_call() and patched_class_call() in _sanitize_value(). The remediation is comprehensive for known dictionary keys, Pydantic models, and CrewAI BaseLLM subclasses. However, custom non-Pydantic Python classes that do not inherit from pydantic.BaseModel or BaseLLM and are not expanded into dict structures will fall through to return val in _sanitize_value_impl(), which could still allow sensitive fields in custom third-party wrapper objects to be stringified if attached directly to an Agent.

Exploitation and Proof-of-Concept

Exploiting or triggering this vulnerability requires no specialized attacker action during execution; the credential leakage occurs automatically whenever an application running a vulnerable MLflow version (>= 2.19.0, < 3.17.0) enables mlflow.crewai.autolog() and instantiates a CrewAI LLM with an api_key argument. An adversary with low-privileged read access (PR:L) to the MLflow tracking server, artifact store, or connected OTLP telemetry backend can subsequently harvest the exposed keys over the network (AV:N).

During a single standard crew.kickoff() execution, a single API key is duplicated across five distinct attribute locations spanning two separate OpenTelemetry spans:

  1. Agent Span (e.g., Support Responder):
    • attributes.llm
    • attributes.function_calling_llm
    • attributes.agent_executor
    • attributes.mlflow.spanInputs
  2. Task Span (e.g., Task.execute_sync):
    • attributes.mlflow.spanInputs

PoC 1: In-Memory Attribute Extraction

The following proof-of-concept demonstrates the underlying serialization flaw directly in memory without requiring an active network connection, external LLM API call, or running MLflow server:

import importlib
from crewai import LLM, Agent
 
# Load the internal MLflow CrewAI autologging module
autolog = importlib.import_module("mlflow.crewai.autolog")
 
# Initialize a CrewAI LLM instance with an explicit API key
llm = LLM(
    model="gpt-4.1-mini",
    api_key="sk-proj-EXAMPLE1234567890",
)
 
agent = Agent(
    role="r",
    goal="g",
    backstory="b",
    llm=llm,
)
 
# Invoke the vulnerable attribute extraction routine
attrs = autolog._get_agent_attributes(agent)
 
# Verify that the plaintext API key is embedded in the serialized 'llm' attribute
assert "sk-proj-EXAMPLE1234567890" in attrs["llm"]
print("Leaked attribute string:")
print(attrs["llm"])

Executing this script on MLflow < 3.17.0 produces output matching the following structure:

Leaked attribute string:
llm_type='openai' model='gpt-4.1-mini' ... api_key='sk-proj-EXAMPLE1234567890' ...

PoC 2: End-to-End OTLP Telemetry Exfiltration

To observe the credential leak across the network via MLflow's OpenTelemetry exporter, configure the environment to point to a local OTLP HTTP receiver:

export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:4318/v1/traces
export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf
export CREWAI_DISABLE_TELEMETRY=true

Next, execute a minimal CrewAI workflow with MLflow autologging enabled:

import mlflow
from crewai import Agent, Crew, LLM, Task
 
mlflow.crewai.autolog()
 
llm = LLM(
    model="gpt-4.1-mini",
    api_key="sk-proj-EXAMPLE1234567890",
)
 
agent = Agent(
    role="Support Responder",
    goal="Answer support questions",
    backstory="A support agent",
    llm=llm,
)
 
task = Task(
    description="Answer the user's question",
    expected_output="A response",
    agent=agent,
)
 
crew = Crew(
    agents=[agent],
    tasks=[task],
)
 
try:
    crew.kickoff()
except Exception:
    # Even when the LLM API call fails due to a dummy key, spans are emitted
    pass

Even though crew.kickoff() raises an authentication exception against the upstream LLM provider when using a synthetic key, MLflow finalizes and flushes the trace spans prior to exit. Inspecting the incoming protobuf ExportTraceServiceRequest packets on port 4318 reveals sk-proj-EXAMPLE1234567890 transmitted in cleartext within both the span attributes and mlflow.spanInputs.

Impact Assessment

CVE-2026-116691 carries a CVSS v3.1 base score of 6.5 (Medium) with the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. The score reflects high confidentiality impact (C:H) combined with low attack complexity (AC:L) and network accessibility (AV:N), gated only by the requirement for low privileges (PR:L) to read trace data from the tracking server or telemetry platform.

In enterprise machine learning environments, MLflow tracking servers and observability backends (such as Datadog, Honeycomb, Jaeger, or Grafana Tempo) are routinely shared across wide engineering, data science, and operations teams. Developers and analysts who have read-only access to experiment traces for debugging or performance evaluation are frequently not authorized to access production LLM provider credentials. Because the API keys are persisted in plaintext inside trace span metadata, any user with trace viewing permissions can extract production secrets for OpenAI, Anthropic, AWS Bedrock, Azure OpenAI, or other configured providers.

Once an attacker obtains a valid LLM provider API key from the trace logs, they can authenticate directly to the external AI provider API outside the boundary of the MLflow environment. Depending on the scope of the compromised credential, this enables unauthorized consumption of paid inference quotas, access to fine-tuned proprietary models, or retrieval of sensitive organization data stored within provider-managed vector stores, files, and assistants.

> [!NOTE] > While the CVSS vector assigns S:U (Scope Unchanged) and I:N/A:N with respect to the MLflow application itself, the downstream consequence of leaked cloud AI credentials extends to third-party API billing abuse and potential data exfiltration from the upstream LLM provider account.

Remediation and Threat Hunting

Patching and Workarounds

To remediate CVE-2026-116691, upgrade the mlflow package to version 3.17.0 or later, which includes commit 20927930d27f0072fcfeb7f024f24ad8c5e77c47:

pip install --upgrade "mlflow>=3.17.0"

If immediate upgrading is blocked by dependency constraints, apply one of the following workarounds:

  1. Disable CrewAI Autologging: Explicitly disable the CrewAI instrumentation in application code by calling mlflow.crewai.autolog(disable=True).
  2. Use Environment Variables for Credentials: Avoid passing the api_key argument directly to the LLM(...) constructor in Python code. Instead, rely on standard provider environment variables (such as OPENAI_API_KEY or ANTHROPIC_API_KEY) read implicitly by the underlying SDKs at request time, ensuring the key is not stored directly on the LLM instance's __dict__.

Post-Upgrade Verification

Platform engineers can verify that an environment is no longer vulnerable by executing the following verification check:

import importlib
from crewai import LLM, Agent
 
autolog = importlib.import_module("mlflow.crewai.autolog")
llm = LLM(model="gpt-4o-mini", api_key="sk-test-SECRETKEY12345")
agent = Agent(role="test", goal="test", backstory="test", llm=llm)
 
attrs = autolog._get_agent_attributes(agent)
if "sk-test-SECRETKEY12345" in str(attrs):
    print("[-] VULNERABLE: Cleartext API key found in agent attributes.")
else:
    print("[+] PATCHED: Credentials sanitized from agent attributes.")

Threat Hunting and Incident Response

Upgrading MLflow prevents future leaks but does not retroactively sanitize historical traces stored in backend databases or external observability platforms. Security teams must conduct retrospective threat hunting across all trace repositories that ingested data from MLflow versions 2.19.0 through 3.16.x:

  1. Audit Stored Spans: Query MLflow backend storage (SQL databases, artifact buckets) and OTLP collectors for spans generated by CrewAI containing the attributes attributes.llm, attributes.function_calling_llm, attributes.agent_executor, and attributes.mlflow.spanInputs.
  2. Scan for Credential Patterns: Apply regular expressions against stored span JSON payloads to identify exposed keys:
    • OpenAI Project Keys: sk-proj-[A-Za-z0-9_-]+
    • Standard OpenAI Keys: sk-[A-Za-z0-9]{32,}
    • Stringified Key Assignments: api_key=['"][^'"]+['"]
    • Bearer Tokens: Bearer\s+[A-Za-z0-9\._\-]+
  3. Rotate and Purge: Immediately revoke and rotate any API key that was passed to a CrewAI LLM object while mlflow.crewai.autolog() was active, and purge or redact the affected trace records from all storage backends.

Official Patches

MLflowOfficial fix commit in mlflow/mlflow repository
MLflowPull Request #25845 remediating CrewAI autologging credential leak
MLflowMLflow v3.17.0 release containing the security patch
GitHubOfficial GitHub Security Advisory (GHSA-j7qq-vr8c-xvw3)

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Affected Systems

MLflow (PyPI package: mlflow) versions >= 2.19.0, < 3.17.0 using mlflow.crewai.autolog()

Affected Versions Detail

Product
Affected Versions
Fixed Version
mlflow
MLflow
>= 2.19.0, < 3.17.03.17.0
AttributeDetail
CVE / Advisory IDCVE-2026-116691 / GHSA-j7qq-vr8c-xvw3
Primary CWECWE-532 (Insertion of Sensitive Information into Log File)
CVSS v3.1 Score6.5 Medium (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N)
Attack VectorNetwork (Telemetry / Trace Backend Retrieval)
Affected Componentmlflow.crewai.autolog (mlflow/crewai/autolog.py)
Affected Versions>= 2.19.0, < 3.17.0
Patched Version3.17.0
Exploit StatusProof-of-Concept Publicly Available; Not in CISA KEV

MITRE ATT&CK Mapping

T1552.001Credentials In Files
Credential Access
T1552Unsecured Credentials
Credential Access
T1005Data from Local System
Collection
CWE-532
Insertion of Sensitive Information into Log File

The product writes sensitive information to log files, trace files, or telemetry streams that are accessible to unauthorized actors.

Known Exploits & Detection

GitHub Security AdvisoryOfficial advisory containing both an in-memory serialization reproduction script and an end-to-end OpenTelemetry (OTLP) trace capture proof-of-concept.

Vulnerability Timeline

Security patch authored and committed to MLflow repository via PR #25845 (Commit 20927930d27f0072fcfeb7f024f24ad8c5e77c47).
2026-09-15
Official CVE record (CVE-2026-116691) published by GitHub CNA and indexed in NVD and OSV (GHSA-j7qq-vr8c-xvw3).
2026-10-27

References & Sources

  • [1]GitHub Security Advisory GHSA-j7qq-vr8c-xvw3
  • [2]MLflow Fix Commit 20927930d27f0072fcfeb7f024f24ad8c5e77c47
  • [3]MLflow Pull Request #25845
  • [4]MLflow v3.17.0 Release Notes
  • [5]CVE-2026-116691 Official Record
  • [6]MLflow GitHub 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

•2 minutes 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
0 views•10 min read
•about 1 hour 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
4 views•9 min read
•about 3 hours ago•CVE-2026-116690
7.5

CVE-2026-116690: Arbitrary File Read via Prompt Model Version Source in MLflow

MLflow versions 3.10.0 through 3.16.1 contain a path traversal vulnerability (CWE-22) in the model version creation handler. Specifically, the prompt-specific execution branch in `_create_model_version()` fails to validate schemeless relative paths and evaluates the `mlflow.prompt.is_prompt` tag based on key presence rather than value. An unauthenticated remote attacker on default deployments, or an authenticated low-privilege user on basic-auth deployments, can register a model version with a relative local path as its artifact source and subsequently retrieve arbitrary files from the server filesystem via the `/api/2.0/mlflow/model-versions/get-artifact` endpoint.

Alon Barad
Alon Barad
9 views•9 min read
•about 4 hours ago•CVE-2026-109383
7.4

CVE-2026-109383: Improper Certificate Validation in Node.js Undici Agent Dispatcher

CVE-2026-109383 (GHSA-2m5v-pch6-74hx) is an improper certificate validation vulnerability (CWE-295) in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js. In affected versions, the Agent constructor clones configuration options using a JSON-based deep clone function (util.deepClone), which executes JSON.parse(JSON.stringify(options)). Because JSON serialization omits function properties, custom certificate validation callbacks passed via the tls configuration option—such as tls.checkServerIdentity—are silently stripped before being passed to origin connection pools. Consequently, connections fall back to standard Node.js TLS validation, bypassing custom certificate pinning or hostname verification rules and allowing an Adversary-in-the-Middle (AitM) with a CA-trusted certificate to intercept and modify traffic.

Alon Barad
Alon Barad
6 views•10 min read
•about 5 hours ago•CVE-2026-109829
7.4

CVE-2026-109829: Persistent Cache Poisoning and Cross-User Information Disclosure in Node.js Undici

A cache key origin desynchronization and intermediate Cache-Control suppression vulnerability exists in the Node.js Undici HTTP client library. When an originless Agent composes the redirect and cache interceptors in the order compose(redirect(), cache()) with a shared cache store, cross-origin responses and sensitive redirected resources are stored under the initial request's cache key.

Alon Barad
Alon Barad
8 views•11 min read
•about 6 hours ago•CVE-2026-109855
7.5

CVE-2026-109855: Denial of Service via Unhandled Stream Error in Node.js Undici HTTP/2 WebSockets

CVE-2026-109855 is a high-severity Denial of Service (DoS) vulnerability in undici, the primary HTTP/1.1 and HTTP/2 client library for Node.js maintained under the OpenJS Foundation. In versions 8.11.0 and 8.11.1, the WebSocket client fails to properly terminate underlying ClientHttp2Stream instances when an HTTP/2 WebSocket handshake fails validation. When the remote server subsequently closes or resets the stream, Node.js emits an unhandled error event on the orphaned stream, crashing the client process.

Alon Barad
Alon Barad
9 views•9 min read