Stanza 1.14.0 reopens pickle RCE that weights_only=True can't block
Upgrading Stanza past 1.12.2 fixed one pickle code-execution path, but 1.14.0 added a second one in the lemmatizer that weights_only=True does not see; 1.15.0 fixes it.
Automated engineering analysis by the Khalid Aboubakr Engineering Desk, from the primary sources listed below. Not reviewed by a person before publication. About the desk
Bottom line
Both Stanza pickle code-execution flaws are patched: CVE-2026-54499 in 1.12.2 and CVE-2026-115878 in 1.15.0. Teams that upgraded to 1.12.2 and moved on to 1.14.0 are exposed again if their code loads a lemmatizer checkpoint from a path a caller, shared store or custom registry can influence. Upgrade to 1.15.0 and treat every Stanza model file as executable code.
What happened
Stanza, the Stanford NLP Python library, has two separate deserialization flaws that both lead to arbitrary code execution when a malicious .pt model file is loaded.
CVE-2026-54499 / GHSA-v5jw-96jm-7h2c. Before 1.12.2, Stanza loaders such as Pretrain.load() tried torch.load(..., weights_only=True) and, on an attacker-triggerable pickle.UnpicklingError, reloaded the same file with weights_only=False (NVD). The advisory also notes that the lemma classifier loader called torch.load with no weights_only argument, which defaults to False on PyTorch older than 2.6 (advisory). Affected: 1.12.1 and earlier. Fixed: 1.12.2, which enforces weights_only=True in all model loaders and makes legacy models that cannot load safely raise an exception (release notes). CVSS 3.1 base score 7.5 (AV:N/AC:H/PR:N/UI:R).
CVE-2026-115878 / GHSA-gh9r-c94j-cmp5. Since 1.14.0 the lemmatizer stores pos_dict as a gzip-compressed pickle inside the checkpoint (advisory). The outer torch.load uses weights_only=True, but the nested bytes are treated as a primitive and never inspected by its allowlist; the decompressed stream then goes to an unrestricted pickle.loads (NVD). Execution happens during pipeline construction via a caller-influenced lemma_model_path, before any inference input is processed. The advisory states explicitly that this is not the fallback fixed under CVE-2026-54499. Fixed: 1.15.0. CVSS 3.1 base score 7.8 (AV:L/AC:L/PR:N/UI:R).
Why it matters
The common remediation story for PyTorch pickle risk is "load with weights_only=True". Stanza 1.12.2 did exactly that, and many teams will have closed CVE-2026-54499 on that basis. CVE-2026-115878 shows the flag only protects the outer pickle stream. Any library that embeds serialized bytes inside a checkpoint and deserializes them itself has stepped outside that protection, and the flag gives a false sense of safety.
Who is affected in practice: services, notebooks, CI jobs and training nodes that build a Stanza pipeline with a lemmatizer model path they do not fully control, or that pull lemma models from shared caches, artifact stores or custom registries. The advisory notes that MD5 verification exists only in the default registry download flow; caller-supplied paths get no checksum. A pipeline that only uses stock models fetched through the default flow is far less exposed to the second CVE.
The CVSS vectors differ (network/high complexity for the first, local/low complexity for the second), but both require a malicious file to reach the loader. Do not read the "Local" vector as "low risk": in an NLP service, a model path that comes from configuration, a tenant setting or a shared bucket is the attack surface.
Engineering assessment
Our assessment: this is a high-priority but narrowly scoped upgrade. The real question is not "which Stanza version" alone but "who can write to, or choose, the model files our process loads". If the answer is "only our build pipeline, from the default registry", exposure to CVE-2026-115878 is limited. If model paths are configurable per tenant, synced from shared storage, or fetched from third-party hubs, treat it as remote code execution in the process that builds the pipeline, with that process's credentials.
Three points the announcements underplay:
- "Past 1.12.2" is not a security baseline. The regression arrived in a later feature release. Version gates in dependency policies should be per-advisory, not "newer than the last fix".
- Execution happens at construction, not inference. Input sanitisation, request validation or a WAF in front of the NLP endpoint does nothing here. The trigger is model loading, which often runs at container start-up with broad environment credentials.
- The legacy-model workaround reintroduces the first flaw. The vendor's advice for checkpoints that fail on 1.12.2+ is to load and resave them with an older release such as 1.12.1, which still has the unsafe fallback. That is acceptable only for files whose provenance is already trusted, and it should run in a throwaway environment.
Compatibility risk from 1.15.0 is not documented in the evidence. The advisory proposes restricting the inner unpickler to plain containers, under which a legitimate pos_dict (a string mapping) would still load, but the evidence does not confirm what the shipped fix does or whether 1.14.0 lemma checkpoints need regenerating. Budget a model-load regression test rather than assuming a drop-in upgrade.
The broader lesson for teams building AI applications: any model artefact in a pickle-based format is code. weights_only=True narrows the outer risk; it does not make a file safe to load from an untrusted source.
Is this you?
stanza1.14.0 is installed (NVD and OSV describe the range as from 1.14.0 until 1.15.0; the GitHub advisory lists only 1.14.0).stanza1.12.1 or earlier is installed (CVE-2026-54499).- Your code passes
lemma_model_pathtostanza.Pipeline, especially from configuration, user input or tenant settings. - Stanza models are read from shared network storage, object storage, an artefact store, a custom registry or a third-party hub rather than the default download flow.
- On Stanza 1.12.1 or earlier with PyTorch older than 2.6, the lemma classifier loads without
weights_onlyat all. - The process that builds the pipeline holds cloud, database or registry credentials.
What to do
- Inventory now. Check every environment, image and lockfile:
pip show stanza python -c "import stanza; print(stanza.__version__)" pip show torch - Upgrade to 1.15.0. It is the first version patched for CVE-2026-115878 and is above the 1.12.2 fix for CVE-2026-54499:
Pin it in requirements or lockfiles and rebuild container images; do not rely on a floating constraint.pip install --upgrade "stanza>=1.15.0" - Test model loading before rollout. Build each production pipeline (including custom lemma, pretrain and classifier models) against 1.15.0 in staging. Since 1.12.2, legacy checkpoints that cannot load safely raise an exception.
- Handle legacy checkpoints carefully. The vendor's guidance is to load and resave failing models with an older version such as 1.12.1. Do this only for files from a trusted origin, in an isolated environment with no credentials (isolation is Not vendor guidance).
- Until upgraded, close the path. Not vendor guidance: stop accepting
lemma_model_pathvalues from users or tenants, restrict write access to model directories and buckets, and pin your own hashes for every custom model file, since caller-supplied paths get no checksum. - Reduce blast radius. Not vendor guidance: build pipelines in a process without long-lived cloud keys in its environment, and treat model-loading workers as untrusted-code runners.
- For technical leads. Not vendor guidance: audit your own code for any
pickle.loadsapplied to bytes taken out of a checkpoint; the same bypass ofweights_only=Trueapplies to in-house loaders. Track the Engineering Desk news for follow-ups.
What we don't know yet
- Whether any 1.14.x release other than 1.14.0 exists and is affected; the GitHub advisory and NVD describe the range differently.
- Whether the 1.15.0 fix changes how lemma checkpoints created by 1.14.0 load, or whether they need regenerating.
- Whether other loaders in 1.15.0 deserialize nested bytes or non-tensor values outside the
weights_only=Trueallowlist. - How the differing CVSS vectors (network/high complexity versus local/low complexity) map to real exposure; the desk's view is that deployment model matters more than either score.
The desk will check the 1.15.0 release notes and fix commit for checkpoint-compatibility details and any further advisories against Stanza loaders.
Sources
Latest engineering analysis
Engineering Practice6 min read
Laravel 13.40.0: transaction, replica and Redis changes to test first
A point release that changes how database-heavy Laravel apps behave under failure, plus a security-flavoured Concurrency fix that ships with no advisory.
6 min read
SD-JWT JS silently drops tampered disclosures and reports success (CVE-2026-62374)
A verifier-side conformance gap in the OpenWallet Foundation's SD-JWT JavaScript libraries lets a credential holder silently remove a claim, and key binding does not stop it.
7 min read
Amazon Redshift JDBC Driver CVE-2026-119084: unsafe class loading fixed in 2.3.0
AWS has fixed an unsafe-reflection flaw in the Amazon Redshift JDBC Driver in 2.3.0, but exposure depends on who controls your connection strings and what sits on your classpath.