Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-54413

CVE-2025-54413: skops Python Library RCE Vulnerability

CVE-2025-54413 is a remote code execution flaw in skops Python library that exploits MethodNode inconsistency to achieve arbitrary code execution at load time. This article covers technical details, affected versions, and patches.

Published:

CVE-2025-54413 Overview

CVE-2025-54413 affects skops, a Python library for sharing and shipping scikit-learn based machine learning models. Versions 0.11.0 and below contain an inconsistency in MethodNode that allows attackers to access unexpected object fields through dot notation during model loading. This flaw enables arbitrary code execution when a victim loads a maliciously crafted skops model file. The issue is categorized under CWE-351: Insufficient Type Distinction and is more severe than the related advisory GHSA-m7f4-hrc6-fwg3 because it relies on fewer assumptions about trusted types. The vulnerability is fixed in skops version 0.12.0.

Critical Impact

Loading an untrusted skops model file triggers arbitrary code execution in the context of the user, compromising confidentiality, integrity, and availability of the host.

Affected Products

  • skops Python library versions 0.11.0 and below
  • Workflows using skops.io.load to deserialize untrusted model files
  • Machine learning pipelines that ingest skops-format models from external sources

Discovery Timeline

  • 2025-07-26 - CVE-2025-54413 published to NVD
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-54413

Vulnerability Analysis

The skops library implements a custom serialization format intended as a safer alternative to Python pickle for scikit-learn models. During load, skops audits each node before instantiating objects, and MethodNode represents a bound method retrieved from a parent object via attribute access. The inconsistency in MethodNode allows the loader to resolve attributes through dot notation on objects that the audit logic did not adequately constrain. An attacker who controls a serialized skops file can chain attribute lookups to reach callables outside the allow-listed surface. When the loader subsequently invokes the resolved callable, attacker-chosen code executes inside the Python process performing the load.

Root Cause

The root cause is insufficient verification of the data source ([CWE-351]) inside MethodNode and OperatorNode audit logic. The audit assumed certain trusted type invariants that the surrounding deserialization code did not enforce, allowing a malicious file to redirect attribute resolution to unintended fields. The fix in pull request #482 hardens both nodes and tightens the constraints on __reduce__ outputs so that reconstruction only proceeds when the produced type matches type(obj).

Attack Vector

Exploitation requires a victim to load an attacker-supplied skops file using skops.io.load or equivalent APIs. The attack vector is local in CVSS terms because the malicious payload must reach the victim's machine, but skops files are routinely fetched from model registries, shared notebooks, and collaboration platforms. User interaction is required to initiate the load. No prior authentication on the target system is needed.

text
# Patch excerpt from docs/changes.rst (skops v0.12)
# Source: https://github.com/skops-dev/skops/commit/0aeca055509dfb48c1506870aabdd9e247adf603

v0.12
-----
- `huggingface_hub` dependency is now optional. :pr:`462` by `Adrin Jalali`_.
- Objects' `__reduce__` is used when the output of it is of the form
  `(type, (constructor_args,)` where type is the same as the `type(obj)`.
  :pr:`467` by `Adrin Jalali`_.
- `MethodNode` and `OperatorNode` have a hardened audit now, removing certain security
  vulnerabilities. :pr:`482` by `Adrin Jalali`_.

Source: GitHub commit 0aeca05

Detection Methods for CVE-2025-54413

Indicators of Compromise

  • Unexpected child processes spawned by Python interpreters shortly after calls to skops.io.load.
  • Outbound network connections or file writes originating from data science workloads immediately after a skops model is opened.
  • skops .skops archive files received from untrusted sources or shared drives, such as the ones referenced in the advisory's supporting materials.

Detection Strategies

  • Inventory Python environments and flag any installation where skops version is <= 0.11.0, for example via pip show skops or SBOM tooling.
  • Inspect skops archives for MethodNode or OperatorNode entries that reference attributes outside the scikit-learn or NumPy module trees.
  • Hunt in EDR telemetry for python or jupyter processes invoking shells, os.system, or subprocess immediately after reading .skops files.

Monitoring Recommendations

  • Log all model-loading operations in MLOps pipelines and forward them to a central SIEM for correlation with process and network events.
  • Alert on data science hosts where Python processes execute interpreters or shells with non-standard command lines.
  • Monitor model registries and shared storage for newly uploaded skops files, and track provenance back to the original contributor.

How to Mitigate CVE-2025-54413

Immediate Actions Required

  • Upgrade skops to version 0.12.0 or later with pip install --upgrade "skops>=0.12.0" across all data science and production environments.
  • Block loading of skops files originating from untrusted authors until the upgrade is complete.
  • Audit recent skops model ingestion events and validate the integrity and source of any files loaded by skops 0.11.0 or earlier.

Patch Information

The issue is fixed in skops v0.12.0 via pull request #482, which hardens the audit logic for MethodNode and OperatorNode. Details are documented in the GitHub Security Advisory GHSA-4v6w-xpmh-gfgp, the v0.12.0 release notes, and the fix commit 0aeca05.

Workarounds

  • Restrict skops model loading to files from cryptographically verified, internal sources only.
  • Run model deserialization inside sandboxed containers or restricted user accounts with no outbound network access.
  • Use the trusted parameter of skops.io.load to explicitly enumerate allowed types and reject any file that requires additional trusted types.
bash
# Upgrade skops to the patched release across environments
pip install --upgrade "skops>=0.12.0"

# Verify the installed version
python -c "import skops, sys; print(skops.__version__); sys.exit(0 if skops.__version__ >= '0.12.0' else 1)"

# Example of constrained loading with an explicit trusted-type allow-list
python - <<'PY'
from skops.io import load, get_untrusted_types
path = "model.skops"
untrusted = get_untrusted_types(file=path)
if untrusted:
    raise SystemExit(f"Refusing to load: untrusted types present: {untrusted}")
model = load(path, trusted=[])
PY

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.