
Python StateMachine 3.0.0 < 3.2.0 RCE via une évaluation non sécurisée de SCXML <data expr> et une injection Python eval().
Gravité : Critique, CVSS 4.0 9.3, CVSS 3.1 9.8 (attribuée par VulnCheck, le CNA)
Vecteur (v4.0) : CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Vecteur (v3.1) : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affecté : Python StateMachine >= 3.0.0, < 3.2.0
Corrigé dans : 3.2.0
CWE : CWE-95 (Neutralisation incorrecte des directives dans le code évalué dynamiquement, injection eval) ; correspond également à CWE-94 (Contrôle incorrect de la génération de code, injection de code)
Découvert et signalé par : Sai Teja Erukude
Publié : 17 juin 2026
Les versions 3.0.0 à 3.2.0 exclue de Python StateMachine contiennent une vulnérabilité d'exécution de code à distance dans le chemin de traitement SCXML.
Le SCXMLProcessor accepte les documents SCXML et conserve les attributs d'expression tels que <data expr="...">. Dans les versions vulnérables, ces chaînes d'expression passent par le chemin de traitement du datamodel SCXML et atteignent finalement la fonction intégrée eval() de Python sans isolation (sandbox).
Un attaquant capable de fournir ou d'influencer un document SCXML peut placer du code Python à l'intérieur d'un attribut <data expr="...">. Lorsque l'application consommatrice analyse le fichier SCXML et démarre le processeur, l'expression est évaluée dans le contexte du processus Python hôte.
Un attaquant peut exécuter du code Python arbitraire si une application vulnérable traite du contenu SCXML contrôlé par l'attaquant.
L'exposition peut être distante ou locale selon la manière dont l'application consommatrice reçoit les documents SCXML. Les chemins d'entrée à risque incluent :
Une exploitation réussie peut permettre :
La chaîne d'appels vulnérable signalée à VulnCheck est :
SCXMLProcessor.parse_scxml_file()
SCXMLProcessor.process_definition()
create_datamodel_action_callable()
_create_dataitem_callable()
_eval()
eval()
Le problème est déclenché lorsqu'un élément de datamodel SCXML analysé est évalué au démarrage du processeur.
Le flux de contrôle vulnérable présente deux défaillances de frontière de confiance :
eval() Python brut.Le PoC utilise un attribut <data expr="..."> car ce chemin s'exécute pendant SCXMLProcessor.start(). Passer un dictionnaire globals vide à eval() ne désactive pas les builtins Python ; Python peut toujours injecter des builtins utilisables dans le contexte d'évaluation. Par conséquent, une expression peut accéder à __import__ et exécuter du code Python.
Une charge utile de preuve inoffensive écrit un fichier marqueur local :
<data id="x" expr="__import__('pathlib').Path(...).write_text(...)"/>
Le marqueur n'est créé qu'après l'analyse du document SCXML et l'évaluation de l'expression du datamodel par start().
package_builder.py génère un fichier SCXML local contrôlé par l'attaquant à l'emplacement malicious-charts/data_expr_start.scxml. Le fichier généré contient une charge utile <data expr> bénigne qui écrit marker.txt dans ce répertoire de PoC.
run_poc.py n'installe aucun hook et ne modifie pas le paquet cible. Il importe le paquet publié python-statemachine==3.1.2, analyse le fichier SCXML généré avec SCXMLProcessor.parse_scxml_file(...), démarre le processeur et affiche les preuves du marqueur avant/après.
À exécuter uniquement dans un environnement de test local :
python -m venv .venv
.venv\Scripts\activate
python -m pip install -r requirements.txt
python run_poc.py
Preuves attendues sur les versions vulnérables :
statemachine_version: 3.1.2
installed_package: True
data_marker_before_start: False
data_marker_after_start: True
marker_contents:
python_statemachine_scxml_data_expr_eval_triggered
success: True
Le comportement important est que marker.txt n'existe pas avant start(), puis existe après, ce qui prouve que l'expression SCXML s'est exécutée à l'intérieur du processus Python hôte.
La charge utile est volontairement inoffensive. Elle écrit uniquement cette chaîne de marqueur locale :
python_statemachine_scxml_data_expr_eval_triggered
Il ne lance pas de shell, ne se connecte pas à un service réseau, ne lit pas de secrets, ne supprime pas de données et ne modifie pas de fichiers en dehors du répertoire PoC.
Mettez à niveau vers Python StateMachine 3.2.0 ou une version ultérieure.
Une correction durable devrait éviter d'évaluer le texte d'expression SCXML contrôlé par l'attaquant avec le eval() Python brut. Les approches plus sûres incluent :
eval() brut par un évaluateur d'expressions restreint.Si une mise à niveau immédiate n'est pas possible :
SCXMLProcessor.| Date | Événement |
|---|---|
| 22 mai 2026 | Vulnérabilité soumise à VulnCheck |
| 26 mai 2026 | VulnCheck a initié la divulgation ; CVE-2026-47103 attribué provisoirement |
| 17 juin 2026 | CVE-2026-47103 publié |
Découverte et signalée par Sai Teja Erukude.
La divulgation a été coordonnée via VulnCheck.