Stanza: Remote Code Execution via Unsafe Pickle Deserialization in Model Loaders
Date: 2026-06
Affected: pip/stanza
Attack vector: deserialization
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-54499
CWE: CWE-502
CWE-676
CVSS: 7.5 (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H)

### Summary Stanza 1.12.0 attempts to safely load PyTorch checkpoint files using `torch.load(..., weights_only=True)`, but automatically falls back to the fully unsafe `torch.load(..., weights_only=False)` when the safe load raises `pickle.UnpicklingError`. Because the `UnpicklingError` condition is fully attacker-controllable, any `.pt` file that contains a single unsupported pickle global will trigger it. An attacker who can place a malicious pretrain or model file on disk (via supply-chain compromise, a poisoned model repository, or a shared model cache) can achieve arbitrary code execution on any machine that loads a Stanza NLP pipeline. Code execution occurs inside the Stanza pretrain-loading API, not merely by calling `torch.load` directly. ### Details The vulnerable code is in [pretrain.py#L59-L67](https://github.com/stanfordnlp/stanza/blob/main/stanza/models/common/pretrain.py#L59-L67) (Stanza 1.12.0): ```python try: data = torch.load(self.filename, lambda storage, loc: storage, weights_only=True) except UnpicklingError: data = torch.load(self.filename, lambda storage, loc: storage, weights_only=False) ``` When `weights_only=True` is passed, PyTorch's deserializer raises `pickle.UnpicklingError` for any object whose class or callable is not on the safe-globals allowlist. This is the intended safety mechanism. However, Stanza catches that exception and immediately reloads the **same attacker-controlled file** with `weights_only=False`, which invokes Py


Mitigations:

Architectural layers (MAESTRO):