Vulnerability Intelligence
Model File Formats and Unsafe Deserialization Risk
Why model formats and loaders matter when an AI system receives an untrusted artifact.
A model artifact is data only until the loader, parser, or runtime gives it more power. That boundary is easy to miss: a file named model.bin may contain tensors, a serialized object graph, references to external files, or instructions to import custom code. If an attacker can replace the artifact, influence its path, or exploit a parser, loading can become code execution, denial of service, data exposure, or model-integrity failure. Treat every model file as untrusted input until its provenance, format, loader behavior, and execution environment have been verified.
This page focuses on deserialization risk rather than model quality. It complements AI Supply Chain Security: Models, Data, Code, and Provenance, Model Security: Protecting Weights, Adapters, and Artifacts, and AI Vulnerability Intelligence. Ask what the loader can reconstruct, what extensions are enabled, and what controls contain failure.
Start with a model-loading trust decision
Before an artifact reaches a developer laptop, CI job, conversion worker, or serving process, use an explicit gate:
MODEL LOADING TRUST DECISION
Artifact source → Provenance and integrity → Format identification → Loader configuration → Isolation and resource policy → Static inspection → Controlled load → Behavioral validation → Promotion or rejection
Each arrow is a decision point. A hash proves that bytes match a known artifact; it does not prove that the producer was trustworthy. A signed release improves provenance, but the signing key, build process, and review scope still matter. A file that passes a scanner can still exploit a parser or consume excessive memory. The load should happen only after the application has decided which identity, purpose, and environment are allowed.
Record the artifact digest, source URI or registry, publisher or repository, commit or release, intended model and revision, file format, loader and library versions, configuration flags, scan result, and approver. Keep this evidence with the deployment or job that consumed the file.
A practical format and loader taxonomy
The following taxonomy is a PermsAI risk lens, not a claim that a filename determines behavior. The same extension can be handled safely or dangerously depending on the parser and options.
| Class | Typical capability | Main concern | Safer default |
|---|---|---|---|
| Data-dominant tensor format | Stores numeric tensors and metadata | Parser bugs, resource exhaustion, poisoned weights | Use a maintained tensor-only reader and bounded resources |
| Code/object-deserialization capable | Reconstructs language objects or invokes an object unpickler | Crafted objects can execute code during load | Disable general object loading; use weights-only or a safer format |
| Extensible/custom-operator format | Supports custom operators, plugins, or external data | Native code, path handling, and parser attack surface | Allow only reviewed operators and isolate conversion/serving |
| Packaged code plus data | Repository or bundle includes runtime code | Code may run before or during model use | Pin reviewed revisions; do not enable remote code implicitly |
Classify the actual loader path, not only the marketing name. A “safe” container can still contain an unsafe nested file or a vulnerable converter.
Why pickle-style loading is a security boundary
Python’s official pickle documentation states that unpickling is not secure: malicious pickle data can execute arbitrary code. That is a property of the serialization design, not a special condition requiring a strange filename. Never unpickle an artifact merely because it came from a model hub, a coworker, or an internal bucket. If legacy compatibility requires it, use a dedicated low-privilege worker with no production credentials, tightly bounded network access, a temporary filesystem, and short lifetime.
The key distinction is between reconstructing tensor values and arbitrary application objects. A loader that imports classes or restores callbacks has a larger attack surface than one accepting a constrained tensor schema. Review nested archives and sidecar files; the outer extension does not describe every operation in the pipeline.
PyTorch and the meaning of weights-only loading
PyTorch’s current torch.load documentation warns never to load data from an untrusted source. Its weights_only option restricts the unpickler to a smaller set of types intended for state dictionaries and tensor-like values. PyTorch serialization documentation also describes weights_only=True as the default in recent releases when a custom pickle module is not supplied. That narrows one code-execution path, not every risk.
Treat the setting as one control to verify, not a certificate. A state dictionary can still be malicious in ways that affect downstream behavior, and malformed data can cause denial of service or memory pressure. Confirm the exact PyTorch version, whether a custom pickle module or allowlist is used, whether the application loads a full object rather than a state dictionary, and whether any post-load code imports remote modules. Test the configuration in CI so a library upgrade cannot silently restore broad object loading.
Safer tensor formats still need controls
Hugging Face describes SafeTensors as a tensor-only format designed to avoid the arbitrary-code behavior associated with pickle. That is a valuable reduction in risk for weights exchange. It does not remove every risk: parsers can have vulnerabilities, tensors can be deliberately huge, metadata can be misleading, and poisoned weights can produce unsafe or biased behavior after loading. Use a maintained parser, enforce size and shape limits, and validate that the artifact matches the expected model architecture.
Format conversion is not automatic sanitization. Converting a pickle artifact to SafeTensors first requires loading the source. Perform conversion in quarantine, preserve the original digest, record the converter version and command, and review the resulting artifact before promotion.
ONNX, external data, and custom operators
ONNX is an interchange format, not a blanket security boundary. The ONNX documentation on external data warns that model-controlled paths can create path traversal and symlink or hardlink risks if a consumer writes or resolves files unsafely. An ONNX graph may also use custom operators implemented by native or third-party code. Validate external-data paths against an approved workspace, reject links that escape it, and allow only reviewed operator implementations.
Separate graph parsing, optimization, conversion, and serving. A model that is acceptable for inference may be unsafe for a conversion tool with broader filesystem or network privileges. Pin parser/runtime versions and monitor their security advisories as you would any other dependency.
Provenance is necessary but not sufficient
Prefer artifacts from a controlled registry or release process. Capture a cryptographic digest and verify signatures or attestations when the producer supports them. Bind the digest to a reviewed model identifier and expected architecture; do not let a user-selected URL or mutable “latest” tag choose production bytes.
Repository history, signed commits, and pickle scanners provide useful evidence, but none proves benign intent or absence of parser vulnerabilities. Reconcile source, maintainer, release notes, vulnerability databases, and your own review. Keep newly downloaded models quarantined until checks complete.
Quarantine and isolation architecture
A robust pipeline keeps loading away from the serving control plane:
RECEIVE → HASH AND IDENTIFY → QUARANTINE → STATIC INSPECTION → ISOLATED LOAD/CONVERSION → VALIDATE SHAPES AND BEHAVIOR → APPROVE → SERVE WITH LEAST PRIVILEGE
The isolated worker should run non-root, have no database or cloud credentials, use a disposable filesystem, cap CPU/memory/file descriptors/processes, and use default-deny egress unless a documented dependency requires a proxy. Separate conversion and serving identities. Do not mount a developer home directory, container socket, or production registry write path. Export only the validated artifact and evidence.
Isolation reduces blast radius; it does not make an unsafe loader acceptable. Keep the parser and runtime patched, and treat a sandbox escape as a possible incident requiring credential review.
Loading security versus model behavior
A file can be safe to deserialize yet still be a poisoned model. Weight manipulation, backdoors, and unexpected output are model-integrity concerns. Conversely, a well-intentioned model can be packaged in an object format that executes code during loading. Evaluate both dimensions: loader safety before execution and behavioral safety after a controlled load. Keep test prompts and evaluation data separate from production secrets.
MODEL FORMAT SECURITY MATRIX
| Format/loading class | Can reconstruct executable objects? | Custom-code capability | Typical trust requirement | Safer handling pattern |
|---|---|---|---|---|
| Pickle or general object archive | Yes, by design | Often implicit through imports/reducers | Trusted, reviewed producer and isolated loader | Prefer replacement; if unavoidable, quarantine and remove credentials |
| PyTorch state dictionary with weights-only configuration | Constrained object set; verify exact options | Application may still import code around the load | Reviewed artifact and pinned loader | Enforce weights-only, shape limits, version tests, isolated conversion |
| SafeTensors | Intended for tensor data, not arbitrary objects | None in the tensor payload | Trusted source plus maintained parser | Verify digest, architecture, sizes, and parser version |
| ONNX graph with external data | Graph data; custom operators may execute native code | Possible through custom operators and runtimes | Reviewed graph, operators, and external paths | Allowlist operators, confine paths, isolate conversion and serving |
| Repository or bundle with remote/custom code | Code may run as part of import or inference | Explicit | Reviewed source, pinned revision, and build provenance | Disable implicit remote code; build from reviewed source in CI |
Registries, CI, and serving controls
Use immutable registry references or digest-pinned releases. In CI, reject unexpected formats, oversized tensors, unknown operators, unapproved publishers, and loader options that enable arbitrary code. Generate a software and model bill of materials, scan parser dependencies, and require review when a model or loader changes.
At serving time, run minimum code and permissions for inference. Keep model directories read-only, separate tenant data, limit runtime network access, and monitor unusual file reads, child processes, outbound connections, and memory growth. Verify rollback provenance before restoring.
Verification and incident response
Useful tests include: loading a malformed or truncated file; oversized tensors; nested archives; unexpected external-data paths; symlink or hardlink handling; unknown custom operators; weights-only enforcement; conversion in a credential-free worker; parser timeout and cancellation; and a registry downgrade attempt. Assert that failed loads leave no promoted artifact and no persistent files.
If a model loader or artifact is suspected, stop promotion, isolate affected workers, preserve digests and logs, revoke credentials available to the loader, identify every job and service that consumed the artifact, and compare deployed bytes with the approved digest. Rotate keys when exposure is plausible. Do not rely on telling an agent to stop; revoke the execution path and disable the affected integration.
Practical checklist
- Identify every format, nested file, parser, converter, and loader option in the path.
- Prefer tensor-only formats and constrained loading modes where they meet the use case.
- Verify digest, source, revision, signature or attestation, architecture, and expected size.
- Quarantine before parsing, conversion, indexing, or serving.
- Run loaders as low-privilege, credential-free workers with bounded CPU, memory, storage, time, and network.
- Disable implicit custom or remote code; review operators and external-data paths.
- Pin and continuously patch serialization, parser, runtime, and conversion dependencies.
- Record provenance, configuration, scan results, approvals, and promotion decisions.
- Test rejection, cleanup, rollback, and revocation paths—not only successful inference.
Sources
- Python pickle documentation — official warning that unpickling untrusted data can execute arbitrary code.
- PyTorch torch.load documentation — current loader behavior and the untrusted-source warning.
- PyTorch serialization notes — weights-only behavior and limitations.
- Hugging Face SafeTensors documentation — tensor-only format rationale.
- Hugging Face pickle scanning guidance — scanning and provenance considerations.
- ONNX external data security documentation — path and external-file handling risks.
- OWASP AI Supply Chain Security guidance — supply-chain and model-integrity context.