Insertion of Sensitive Information into Log File Affecting mlflow package, versions [2.19.0,3.17.0)


Severity

Recommended
0.0
high
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept
EPSS
0.21% (11th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PYTHON-MLFLOW-21756863
  • published27 Oct 2026
  • disclosed27 Oct 2026
  • creditIdoGol24

Introduced: 27 Oct 2026

NewCVE-2026-116691  (opens in a new tab)
CWE-312  (opens in a new tab)
CWE-532  (opens in a new tab)

How to fix?

Upgrade mlflow to version 3.17.0 or higher.

Overview

mlflow is a platform to streamline machine learning development, including tracking experiments, packaging code into reproducible runs, and sharing and deploying models.

Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File via mlflow.crewai.autolog in mlflow/crewai/autolog.py, where LLM credentials such as API keys are serialized into MLflow trace spans without sanitization. When a CrewAI LLM object is configured with an API key and autologging is enabled, the credential is recorded in plaintext across span attributes (including attributes.llm, attributes.function_calling_llm, attributes.agent_executor, and attributes.mlflow.spanInputs) and exported through the OTLP telemetry path, making it accessible to anyone with read access to the MLflow trace store or the OTLP receiver.

Note: This is only exploitable when mlflow.crewai.autolog() is enabled and a CrewAI LLM is configured with an API key.

PoC

Environment:

MLflow: 3.16.0
CrewAI: 1.15.18
Python: 3.12.3
opentelemetry-exporter-otlp-proto-http: 1.42.1

1. Direct serialization proof

The following demonstrates the vulnerability without starting a Crew, making a network request, or requiring an MLflow server:

import importlib
from crewai import LLM, Agent

autolog = importlib.import_module("mlflow.crewai.autolog")

llm = LLM( model="gpt-4.1-mini", api_key="sk-proj-EXAMPLE1234567890", )

agent = Agent( role="r", goal="g", backstory="b", llm=llm, )

attrs = autolog._get_agent_attributes(agent)

assert "sk-proj-EXAMPLE1234567890" in attrs["llm"]

print(attrs["llm"])

The output contains the API key in plaintext, for example:

llm_type='openai' model='gpt-4.1-mini' ... api_key='sk-proj-EXAMPLE1234567890' ...

No provider request is required.

#

2. End-to-end trace disclosure

The issue can also be reproduced through MLflow's actual OTLP exporter.

Configure a local OTLP HTTP receiver and set:

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

Then run:

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], )

crew.kickoff()

A local OTLP receiver can decode the ExportTraceServiceRequest sent by MLflow.

The provider request is expected to fail because the credential is intentionally fake. This does not affect the vulnerability: the sensitive value is added to the MLflow span when the instrumentation starts, before the provider call succeeds or fails.

In the tested environment, the fake API key appeared in the exported telemetry in 5 locations across 2 spans, including:

Support Responder
  attributes.llm
  attributes.function_calling_llm
  attributes.agent_executor
  attributes.mlflow.spanInputs

Task.execute_sync attributes.mlflow.spanInputs

The captured value is produced by MLflow's actual telemetry/export path rather than being manually inserted into a span.

All credentials used in the reproduction are locally generated fake values. No real API credential is required.

Note: The PoC states it was tested with MLflow 3.16.0, CrewAI 1.15.18, Python 3.12.3, and opentelemetry-exporter-otlp-proto-http 1.42.1.

CVSS Base Scores

version 4.0
version 3.1