CVE-2025-10155: Picklescan Picklescan Bypass Is Possible Vulnerability

CRITICAL
Advisory Identifier: GHSA-jgw4-cr84-mqxg
CVSS 7.8
CWE-693 CWE-20
Published
Advisory Summary

CVE-2025-10155 is a CRITICAL (CVSS 7.8) picklescan bypass is possible vulnerability (CWE-693: Protection Mechanism Failure) affecting Picklescan libraries in the PyPI ecosystem. The issue involves picklescan bypass is possible via file extension mismatch. Remediation is available by upgrading affected packages to version 0.0.31.

CVE-2025-10155 at a Glance

CVE Identifier CVE-2025-10155
GHSA Identifier GHSA-jgw4-cr84-mqxg
Severity CRITICAL
CVSS v3.1 Base Score 7.8
CWE Classification CWE-693: Protection Mechanism Failure
Affected Product Picklescan
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 7.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H).

Attack Vector Local (AV:L)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2025-10155

To remediate this vulnerability, upgrade all affected Picklescan dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

picklescan fixed: 0.0.31
pip install picklescan>=0.0.31
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show picklescan

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2025-10155, inspect your installed packages using pip:

pip show picklescan

Analyze the terminal output to locate any version of Picklescan in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.0.31), your application is affected.

Note: The pip show picklescan command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-693: Protection Mechanism Failure, where the product does not use or incorrectly uses a protection mechanism that provides sufficient defense against directed attacks against the product. In Picklescan, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary Picklescan can be bypassed, allowing the detection of malicious pickle files to fail, when a standard pickle file is given a PyTorch-related file extension (e.g., .bin). This occurs because the scanner prioritizes PyTorch file extension checks and errors out when parsing a standard pickle file with such an extension instead of falling back to standard pickle analysis. This vulnerability allows attackers to disguise malicious pickle payloads within files that would otherwise be scanned for pickle-based threats. ### Details The vulnerability stems from the logic in the scan_bytes function within picklescan/scanner.py, specifically around line 463:[ https://github.com/mmaitre314/picklescan/blob/75e60f2c02f3f1a029362e6f334e1921392dcf60/src/picklescan/scanner.py#L463](https://github.com/mmaitre314/picklescan/blob/75e60f2c02f3f1a029362e6f334e1921392dcf60/src/picklescan/scanner.py#L463) The code first checks if the file extension (file_ext) is in the pytorch_file_extension list. If it is (e.g., .bin), the scan_pytorch function is called. When a standard pickle file is encountered with a PyTorch extension, scan_pytorch will likely fail. Critically, the code then returns an Error without attempting to analyze the file as a standard pickle using scan_pickle_bytes. This prevents the detection of malicious payloads within such files. ### PoC - Download a malicious pickle file with a standard .pkl extension: wget <https://huggingface.co/kzanki/regular_model/resolve/main/model.pkl?download=true> -O model.pkl - Scan the file with Picklescan (correct detection): /home/davfr/Tests/HF/dangerous_model/model.pkl: dangerous import 'builtins exec' FOUND ----------- SCAN SUMMARY ----------- Scanned files: 1 Infected files: 1 Dangerous globals: 1 - Rename the file to use a PyTorch-related extension (e.g., .bin): cp model.pkl model.bin - Scan the renamed file with Picklescan: ![Screenshot 2025-06-29 at 9 38 13](https://github.com/user-attachments/assets/29a7886f-2d0e-48ca-832d-9a6699ae09f1) **Observed Result:** Picklescan fails and reports an error related to PyTorch parsing but does not detect the malicious pickle content. **Expected Result**: Picklescan should recognize the file as a standard pickle format despite the .bin extension and scan it accordingly, identifying the malicious content. ### Impact **Severity**: High **Affected Users**: Any organization or individual relying on Picklescan to ensure the safety of PyTorch models or other files that might contain embedded pickle objects. This includes users downloading pre-trained models or receiving files that could potentially contain malicious code. **Impact Details**: Attackers can craft malicious pickle payloads and disguise them within files using common PyTorch extensions (like .bin, .pt, etc.). These files would then bypass PickleScan's detection mechanism, allowing the malicious code to execute when the file is loaded by a vulnerable application or user. **Potential Exploits**: This vulnerability significantly weakens the security provided by PickleScan. It opens the door to various supply chain attacks, where malicious actors could distribute backdoored models through platforms like Hugging Face, PyTorch Hub, or even through direct file sharing. Users trusting PickleScan would be unknowingly exposed to these threats. **Recommendations** The most effective solution is to modify the scanning logic to ensure that standard pickle scanning is attempted as a fallback mechanism when PyTorch scanning fails or is not applicable. A suggested approach is: Attempt PyTorch Scan: If the file extension matches a known PyTorch extension, attempt to scan it as a PyTorch object. Fallback to Pickle Scan: Regardless of the success or failure of the PyTorch scan (or if the extension is not a PyTorch extension), always attempt to scan the file as a standard pickle. This ensures that files with misleading extensions are still analyzed for potential pickle-based vulnerabilities. ### Suggested Patch ``` --- a/src/picklescan/scanner.py +++ b/src/picklescan/scanner.py @@ -462,19 +462,28 @@ def scan_bytes(data: IO[bytes], file_id, file_ext: Optional[str] = None) -> Scan if file_ext is not None and file_ext in pytorch_file_extensions: try: return scan_pytorch(data, file_id) except InvalidMagicError as e: - _log.error(f"ERROR: Invalid magic number for file {e}") - return ScanResult([], scan_err=True) + _log.warning(f"PyTorch scan failed for {file_id} with extension {file_ext}: {e}") + # Don't return error here - continue to other scan methods elif file_ext is not None and file_ext in numpy_file_extensions: - return scan_numpy(data, file_id) - else: - is_zip = zipfile.is_zipfile(data) - data.seek(0) - if is_zip: - return scan_zip_bytes(data, file_id) - elif is_7z_file(data): - return scan_7z_bytes(data, file_id) - else: - return scan_pickle_bytes(data, file_id) + try: + return scan_numpy(data, file_id) + except Exception as e: + _log.warning(f"NumPy scan failed for {file_id}: {e}") + + # Always attempt additional format checks as fallback + data.seek(0) # Reset stream position + is_zip = zipfile.is_zipfile(data) + data.seek(0) + if is_zip: + return scan_zip_bytes(data, file_id) + elif is_7z_file(data): + return scan_7z_bytes(data, file_id) + else: + # FIX: Always attempt pickle scanning as fallback + # This prevents the vulnerability where pickle files with wrong extensions bypass detection + return scan_pickle_bytes(data, file_id) ```

CVE-2025-10155 Affected Picklescan Versions

1 component(s)
Fixed Versions:
0.0.31
Product / Package Ecosystem Affected Versions Fixed Version
picklescan
PyPI
< 0.0.31
0.0.31

References

Frequently Asked Questions

What is CVE-2025-10155?
CVE-2025-10155 is a security vulnerability in Picklescan involving Picklescan Bypass is Possible via File Extension Mismatch under CWE-693: Protection Mechanism Failure.
Which Picklescan versions are affected?
Affected versions include releases prior to 0.0.31 across affected packages: picklescan.
What version fixes CVE-2025-10155?
Upgrading to 0.0.31 (or the latest patched release for your respective branch) resolves the vulnerability.
Is picklescan affected?
Yes, picklescan is affected in releases prior to 0.0.31. Upgrade your dependency to 0.0.31 or later.
What is the CVSS score of CVE-2025-10155?
CVE-2025-10155 has a CVSS v3.1 base score of 7.8 (CRITICAL) with vector string CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2025-10155?
CVE-2025-10155 is classified under CWE-693: Protection Mechanism Failure (The product does not use or incorrectly uses a protection mechanism that provides sufficient defense against directed attacks against the product.).
How can I check PyPI dependencies for CVE-2025-10155?
Run the dependency tree command: 'pip show picklescan'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-jgw4-cr84-mqxg",
  "modified" : "2026-06-06T14:44:23Z",
  "published" : "2025-09-10T19:51:37Z",
  "aliases" : [ "CVE-2025-10155" ],
  "summary" : "Picklescan Bypass is Possible via File Extension Mismatch",
  "details" : "### Summary\nPicklescan can be bypassed, allowing the detection of malicious pickle files to fail, when a standard pickle file is given a PyTorch-related file extension (e.g., .bin). This occurs because the scanner prioritizes PyTorch file extension checks and errors out when parsing a standard pickle file with such an extension instead of falling back to standard pickle analysis. This vulnerability allows attackers to disguise malicious pickle payloads within files that would otherwise be scanned for pickle-based threats.\n### Details\nThe vulnerability stems from the logic in the scan_bytes function within picklescan/scanner.py, specifically around line 463:[ https://github.com/mmaitre314/picklescan/blob/75e60f2c02f3f1a029362e6f334e1921392dcf60/src/picklescan/scanner.py#L463](https://github.com/mmaitre314/picklescan/blob/75e60f2c02f3f1a029362e6f334e1921392dcf60/src/picklescan/scanner.py#L463)\nThe code first checks if the file extension (file_ext) is in the pytorch_file_extension list. If it is (e.g., .bin), the scan_pytorch function is called. When a standard pickle file is encountered with a PyTorch extension, scan_pytorch will likely fail. Critically, the code then returns an Error without attempting to analyze the file as a standard pickle using scan_pickle_bytes. This prevents the detection of malicious payloads within such files.\n### PoC\n- Download a malicious pickle file with a standard .pkl extension:\nwget <https://huggingface.co/kzanki/regular_model/resolve/main/model.pkl?download=true> -O model.pkl\n- Scan the file with Picklescan (correct detection):\n/home/davfr/Tests/HF/dangerous_model/model.pkl: dangerous import 'builtins exec' FOUND\n----------- SCAN SUMMARY -----------\nScanned files: 1\nInfected files: 1\nDangerous globals: 1\n\n- Rename the file to use a PyTorch-related extension (e.g., .bin):\ncp model.pkl model.bin\n- Scan the renamed file with Picklescan:\n![Screenshot 2025-06-29 at 9 38 13](https://github.com/user-attachments/assets/29a7886f-2d0e-48ca-832d-9a6699ae09f1)\n\n**Observed Result:** Picklescan fails and reports an error related to PyTorch parsing but does not detect the malicious pickle content.\n**Expected Result**: Picklescan should recognize the file as a standard pickle format despite the .bin extension and scan it accordingly, identifying the malicious content.\n### Impact\n**Severity**: High\n**Affected Users**: Any organization or individual relying on Picklescan to ensure the safety of PyTorch models or other files that might contain embedded pickle objects. This includes users downloading pre-trained models or receiving files that could potentially contain malicious code.\n**Impact Details**: Attackers can craft malicious pickle payloads and disguise them within files using common PyTorch extensions (like .bin, .pt, etc.). These files would then bypass PickleScan's detection mechanism, allowing the malicious code to execute when the file is loaded by a vulnerable application or user.\n**Potential Exploits**: This vulnerability significantly weakens the security provided by PickleScan. It opens the door to various supply chain attacks, where malicious actors could distribute backdoored models through platforms like Hugging Face, PyTorch Hub, or even through direct file sharing. Users trusting PickleScan would be unknowingly exposed to these threats.\n**Recommendations**\nThe most effective solution is to modify the scanning logic to ensure that standard pickle scanning is attempted as a fallback mechanism when PyTorch scanning fails or is not applicable. A suggested approach is:\nAttempt PyTorch Scan: If the file extension matches a known PyTorch extension, attempt to scan it as a PyTorch object.\nFallback to Pickle Scan: Regardless of the success or failure of the PyTorch scan (or if the extension is not a PyTorch extension), always attempt to scan the file as a standard pickle. This ensures that files with misleading extensions are still analyzed for potential pickle-based vulnerabilities.\n### Suggested Patch\n\n```\n--- a/src/picklescan/scanner.py\n+++ b/src/picklescan/scanner.py\n@@ -462,19 +462,28 @@ def scan_bytes(data: IO[bytes], file_id, file_ext: Optional[str] = None) -> Scan\n     if file_ext is not None and file_ext in pytorch_file_extensions:\n         try:\n             return scan_pytorch(data, file_id)\n         except InvalidMagicError as e:\n-            _log.error(f\"ERROR: Invalid magic number for file {e}\")\n-            return ScanResult([], scan_err=True)\n+            _log.warning(f\"PyTorch scan failed for {file_id} with extension {file_ext}: {e}\")\n+            # Don't return error here - continue to other scan methods\n     elif file_ext is not None and file_ext in numpy_file_extensions:\n-        return scan_numpy(data, file_id)\n-    else:\n-        is_zip = zipfile.is_zipfile(data)\n-        data.seek(0)\n-        if is_zip:\n-            return scan_zip_bytes(data, file_id)\n-        elif is_7z_file(data):\n-            return scan_7z_bytes(data, file_id)\n-        else:\n-            return scan_pickle_bytes(data, file_id)\n+        try:\n+            return scan_numpy(data, file_id)\n+        except Exception as e:\n+            _log.warning(f\"NumPy scan failed for {file_id}: {e}\")\n+    \n+    # Always attempt additional format checks as fallback\n+    data.seek(0)  # Reset stream position\n+    is_zip = zipfile.is_zipfile(data)\n+    data.seek(0)\n+    if is_zip:\n+        return scan_zip_bytes(data, file_id)\n+    elif is_7z_file(data):\n+        return scan_7z_bytes(data, file_id)\n+    else:\n+        # FIX: Always attempt pickle scanning as fallback\n+        # This prevents the vulnerability where pickle files with wrong extensions bypass detection\n+        return scan_pickle_bytes(data, file_id)\n```",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"
  }, {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "picklescan"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.0.31"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 0.0.30"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/mmaitre314/picklescan/security/advisories/GHSA-jgw4-cr84-mqxg"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2025-10155"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/mmaitre314/picklescan/commit/28a7b4ef753466572bda3313737116eeb9b4e5c5"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/mmaitre314/picklescan"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/mmaitre314/picklescan/blob/58983e1c20973ac42f2df7ff15d7c8cd32f9b688/src/picklescan/scanner.py#L463"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pypa/advisory-database/tree/main/vulns/picklescan/PYSEC-2025-151.yaml"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-20", "CWE-693" ],
    "severity" : "CRITICAL",
    "github_reviewed" : true,
    "github_reviewed_at" : "2025-09-10T19:51:37Z",
    "nvd_published_at" : null
  }
}