Exploiter une vulnérabilité TensorFlow (.h5 RCE) : analyse, détection et remédiation
10 sept. 2025

Introduction
Lors d’un test d’intrusion pour un client, nous avons découvert une vulnérabilité TensorFlow critique permettant une Remote Code Execution (RCE) via le chargement de fichiers Keras .h5
malveillants. Cette faille illustre une réalité souvent ignorée : un modèle IA n’est pas qu’un “poids”, c’est un artefact exécutable dont la désérialisation peut déclencher du code Python.
Dans cet article, nous expliquons l’attaque, proposons des méthodes de détection sans exécution, listons des IOCs, et détaillons des mesures de remédiation pragmatiques pour sécuriser vos environnements Machine Learning.
Contexte et threat model
Dans de nombreux SI, des applications internes ou SaaS acceptent l’upload de modèles (use-cases AutoML, fine-tuning, bring-your-own-model). Le serveur d’inférence charge ensuite ces fichiers (souvent .h5
) via load_model()
.
Hypothèses d’attaque réalistes :
Un utilisateur malveillant (ou un compte compromis) uploade un modèle
.h5
piégé.Le backend ML désérialise le modèle sans contrôle et exécute du code arbitraire.
L’attaquant obtient une exécution de commandes (RCE), exfiltre des secrets (clés, credentials, datasets), implante une persistance, puis pivote.
Impact business :
Exfiltration de données sensibles (datasets propriétaires, modèles).
Sabotage / backdoor de modèles mis en prod (perte d’intégrité).
Compromission de l’infra (latérale) via le nœud ML.
Comprendre la vulnérabilité TensorFlow
L’import d’un modèle Keras/TensorFlow se fait classiquement via load_model()
:
Le problème : les modèles .h5
peuvent embarquer des couches Lambda
contenant du code Python sérialisé. Sans politique de validation ni sandbox, le simple chargement peut déclencher une RCE.
Points clés :
Les couches Lambda sont puissantes mais dangereuses hors confiance.
La désérialisation ⇢ exécution potentielle de fonctions Python.
Beaucoup de pipelines ne contrôlent pas (ou mal) ces artefacts.
Preuve de concept (PoC) : fichier .h5 malveillant
Un modèle minimal avec Lambda
peut exécuter une commande système :
Effet : à l’import, le serveur crée /tmp/pwned
. C’est trivial, mais cela prouve l’exécution côté serveur.
De la PoC à une compromission réaliste
Pour un accès interactif, une charge type reverse shell est souvent utilisée (adaptée à l’environnement cible) :
Au chargement, le serveur initie une connexion sortante vers l’attaquant. Avec des règles egress permissives, l’attaquant obtient un shell, élève ses privilèges, dump des secrets (variables d’env, tokens cloud), et pivote.
Astuce défensive : surveiller les connexions sortantes inhabituelles depuis le namespace/Pod de service d’inférence.
Déguiser un fichier .h5 malveillant
L’attaque peut être camouflée dans un modèle légitime (ex. VGG16) :
À l’œil nu (ou via un audit superficiel), le modèle paraît valide. La charge reste latente jusqu’au load_model()
.
Détection hors exécution (safe parsing)
Avant tout chargement, inspectez le .h5
sans exécuter de code :
Bonnes pratiques d’analyse :
Ne jamais appeler
load_model()
pour “voir ce qu’il y a dedans”.Si la structure ne contient pas
Lambda
, restez prudents : d’autres vecteurs (custom objects, wrappers) peuvent exister.Versionnez vos outils d’inspection (variations Keras/TensorFlow).
Indicateurs de compromission (IOCs)
À surveiller si vous suspectez une exploitation .h5
:
Fichiers traces inattendus (ex.
/tmp/pwned
,/var/tmp/*
).Processus éphémères au chargement d’un modèle (shells, interprètes).
Connexions sortantes depuis les nœuds/pods d’inférence vers IP/ports non standard.
Logs d’application : erreurs pendant
load_model()
, anomalies dans les temps de chargement, exceptions de désérialisation.Modèles modifiés : empreintes (hash) qui changent hors cycle d’update, présence de
Lambda
ou d’objets custom inattendus.
Architecture durcie & mitigations
1) Politique d’acceptation des modèles
Interdire l’upload de modèles arbitraires par défaut.
Favoriser des formats déclaratifs (ex. TF-Lite/ONNX) sans exécution Python au chargement.
Si Keras
.h5
est incontournable, bloquerLambda
et objets custom au parsing.
2) Exécution confinée
Charger les modèles dans une sandbox (conteneur non privilégié, AppArmor/SELinux, seccomp,
no-new-privileges
).FS en lecture seule,
/tmp
isolé, network egress control strict.Secrets par injection contrôlée (ex. KMS) — jamais en variables d’environnement “larges”.
3) Pipeline de sécurité
Scan statique des
.h5
(signature, présence deLambda
, heuristiques).Signature des modèles (chaîne de confiance) + vérification en pré-production.
Observabilité : métriques de charge/latence, logs d’accès, eBPF pour syscall sensibles si possible.
4) Gestion des versions
Tenir à jour TensorFlow/Keras et dépendances.
Épingler des versions (requirements) et reconstruire les images régulièrement.
Tests de régression sécurité dans le CI pour les chemins de désérialisation.
Checklist opérationnelle
Interdire
Lambda
/custom objects dans les artefacts utilisateurs.Mettre un parsing sécurisé avant tout chargement.
Confinement fort (conteneur, réseau, FS RO, user non-root).
Bloquer les sorties réseau non nécessaires.
Journaliser et alerter sur les anomalies au chargement.
Inventorier et hasher tous les modèles déployés.
Mettre à jour TensorFlow/Keras + scanner les images.
Former les équipes (dev/DS/ops) à la sécurité ML.
Questions fréquentes (FAQ)
Q1 — Est-ce spécifique à Keras/TensorFlow ?
Principalement oui pour l’exemple Lambda
, mais toute désérialisation de formats “riches” peut poser problème si elle exécute du code (ou charge des objets arbitraires).
Q2 — On peut scanner automatiquement tous nos .h5
?
Oui : mettez un job d’inventaire (cf. annexe) pour lister les modèles, extraire la config et bloquer en CI ceux qui contiennent Lambda
/custom objects.
Q3 — On a besoin de Lambda
pour des raisons légitimes. On fait quoi ?
Restreindre l’usage aux artefacts signés en interne.
Charger en sandbox dédiée, hors prod, et promouvoir ensuite un format neutre (ex. TF-Lite, SavedModel sans code).
Q4 — Pourquoi pas juste “faire confiance” à nos utilisateurs internes ?
La menace interne existe. Et un compte SSO compromis suffit. Appliquez le principe de moindre confiance.
Encadré légal & éthique
Les techniques décrites visent la sécurisation des environnements ML. N’exploitez jamais ces méthodes en dehors d’un cadre légal (contrat d’audit, labo perso). Chez Phorsys, nous conduisons ces tests avec autorisation et dans un but défensif.
Conclusion
Un simple fichier Keras/TensorFlow .h5
malveillant peut suffire à compromettre un serveur si la désérialisation n’est pas contrôlée. En combinant parsing sécurisé, confinement, observabilité, et gouvernance des artefacts, vous réduisez drastiquement le risque.
Chez Phorsys, nous rencontrons régulièrement ce scénario en mission. Besoin d’un audit de vos pipelines IA/ML ou d’une revue d’architecture ? Parlons-en.
Annexe — Scripts utiles
A. Inventaire & scan des .h5
(répertoire)
B. Exemple d’alerte simple (pseudo-CI)
Échec si
lambdas
non vide.Journaliser
hash
+ chemin pour traçabilité.