# Model artifact deserialization code execution

Untrusted model files loaded via pickle, Lambda layers, or forged handles that reach deserialization

_Area: AI and LLM app security. Seen in 3 disclosed reports; latest 2026-10-28. Updated 2026-10-31._

## How it works
Model files are treated as passive data, but several formats embed executable content. Pickle streams reconstruct arbitrary objects on load; Keras Lambda layers serialize Python callables; some caches deserialize byte chunks with `pickle.loads()`. The broken assumption is that loading a model is safe because it is "just weights." Any loader that deserializes attacker-supplied bytes, or trusts a caller-supplied handle to reach a deserializer, runs attacker code in the loading process.

## Where it shows up
- `pickle.load`/`torch.load`/`joblib.load` on files from uploads, hubs, or user paths
- Keras `.h5`/`.hdf5` models with Lambda or custom layers; `safe_mode` not enforced for legacy formats [E3](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2024-machine-learning-attack-series-keras-backdoor-model.md)
- Inference services accepting model uploads and loading them in shared, multi-tenant pods [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-and-hugging-face-address-risks-to-ai-infrastructure.md)
- Public request fields carrying cache handles (address, id) into worker-side deserialization [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-6757-hggm-hp2w.md)
- Loader pods able to reach `169.254.169.254` or internal registries [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-and-hugging-face-address-risks-to-ai-infrastructure.md)

## How to review
Trace every path from an untrusted file or request field to a deserializer. The invariant: no attacker-controlled bytes or handle may reach `pickle.loads` or callable reconstruction without a safe format or a capability bound to the issuer. Check that legacy formats are rejected or scanned, that `safe_mode` applies to all formats, and that cache handles are validated against the cache key or issuer before dereference [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-6757-hggm-hp2w.md). For hosted inference, confirm pods cannot reach IMDS or internal services and that tenants are isolated [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-and-hugging-face-address-risks-to-ai-infrastructure.md).

## Variants seen
- Malicious pickle uploaded to a hosted Inference API, executing in a shared pod [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-and-hugging-face-address-risks-to-ai-infrastructure.md)
- Forged shared-memory handle in a public request field reaching worker `pickle.loads()` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-6757-hggm-hp2w.md)
- Keras Lambda layer in a legacy `.h5` file executing on load [E3](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2024-machine-learning-attack-series-keras-backdoor-model.md)

## Impact and severity
All three reach arbitrary code execution. Severity rises sharply with blast radius: in [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-and-hugging-face-address-risks-to-ai-infrastructure.md) code execution in an inference pod led to IMDS abuse, EKS node role compromise, and cross-tenant access. [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-6757-hggm-hp2w.md) required authentication but gave arbitrary Python execution to any caller. [E3](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2024-machine-learning-attack-series-keras-backdoor-model.md) executed on any machine that loaded the model. Shared multi-tenant hosting and reachable cloud metadata made it worse.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-wiz-and-hugging-face-address-risks-to-ai-infrastructure.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-6757-hggm-hp2w.md
- E3: https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2024-machine-learning-attack-series-keras-backdoor-model.md
