Comment lire ces chiffres
Précision
Sur toutes les alertes levées par le scanner, la proportion qui sont de vraies vulnérabilités. Précision faible = beaucoup de faux positifs à trier.
Définition complète dans le glossaire ↗Recall
Sur toutes les vraies vulnérabilités qui existent, la proportion que le scanner détecte réellement. Recall faible = de vraies failles passent inaperçues — le mode d'échec le plus dangereux.
Définition complète dans le glossaire ↗F1
Un seul chiffre combinant précision et recall. Pratique pour comparer, mais masque lequel des deux tire le score — d'où le choix de cette page de publier les deux séparément, pas juste le F1.
Définition complète dans le glossaire ↗Cinq méthodologies, pas un seul chiffre
Un chiffre unique de « précision » ne veut quasiment rien dire sans savoir comment il a été mesuré. Ces cinq méthodologies produisent des résultats très différents — et de plus en plus honnêtes :
Fixtures internes
Fait tourner chaque règle contre ses propres cas de test appariés (un fichier vulnérable, un fichier propre par règle) — 910 cas sur les 8 langages. Cela mesure si le moteur de règles fait toujours ce pour quoi il a été conçu ; un jeu de règles mature devrait scorer proche de 100% ici quasiment par construction. Utile comme signal de non-régression, pas comme preuve externe de quoi que ce soit.
OWASP Benchmark (Java + Python)
Une suite de test indépendante, tierce (pas écrite par nous), avec une vérité terrain fixe et publiée, exécutée en intégralité pour les deux langages. Plus difficile et plus réaliste que des fixtures maison — c'est la même méthodologie qu'utilisent les études de benchmarking de l'industrie. Construite presque entièrement autour de patterns de code Servlet/HTTP.
NIST Juliet (Java)
Une suite de test synthétique du gouvernement américain (NIST SARD), 6 616 cas sur 6 catégories CWE mappées. Même langage et globalement les mêmes classes de vulnérabilité qu'OWASP Benchmark Java, mais des idiomes de code source bien plus variés — variables d'environnement, fichiers de propriétés, sockets, entrée standard, connexions URL, pas seulement des requêtes HTTP. L'écart entre celui-ci et OWASP Benchmark Java est en soi le signal le plus honnête de cette page.
Suite de tests CVE
Reconstruite à partir de 45 vraies CVE historiques sur 8 frameworks réels (Django, Flask, Express, Spring, ASP.NET, Laravel, plus les bibliothèques standard des deux langages). Le test le plus dur : du vrai code vulnérable tel qu'il a réellement été livré, pas un cas de test idéalisé.
Résultats, exécutés aujourd'hui
| Méthodologie | Cas | Précision | Recall | F1 |
|---|---|---|---|---|
| Fixtures internes (8 langages) auto-validation |
910 | 100.0% | 100.0% | 100.0% |
| OWASP Benchmark (Java) indépendant |
2 740 | 73.7% | 100.0% | 84.8% |
| NIST Juliet (Java) indépendant |
6 616 | 98.4% | 46.7% | 63.3% |
| OWASP Benchmark (Python) indépendant |
1 230 | 78.8% | 96.0% | 86.5% |
| Suite de tests CVE (5 langages) monde réel |
45 | 82.9% | 75.6% | 79.1% |
La comparaison la plus révélatrice de cette page est Java contre lui-même : OWASP Benchmark Java affiche 100,0% de recall, tandis que NIST Juliet — même langage, globalement les mêmes classes CWE, exécuté la même semaine — n'affiche que 46,7%. Ce n'est pas une contradiction, c'est un diagnostic. OWASP Benchmark est construit presque entièrement autour de code source de style Servlet/HTTP ; Juliet teste aussi les variables d'environnement, les fichiers de propriétés, les sockets, l'entrée standard et les connexions URL. Le moteur de règles avait été calibré exactement sur le pattern qu'OWASP Benchmark récompense, et Juliet a exposé l'angle mort. Nous avons déjà corrigé une partie de cet écart ce cycle-ci (le recall Java sur Path Traversal et SQL Injection a globalement doublé après l'élargissement des sources de taint reconnues — voir ci-dessous — et la précision a à peine bougé : 98,2% → 98,4%) et les chiffres actuels de cette page reflètent ce correctif, pas les anciens. Le recall d'OWASP Benchmark Python (96,0%) et de la suite de tests CVE (75,6%) se situent entre les deux, ce qui est en soi instructif : ni aussi étroitement ciblé qu'OWASP Java, ni aussi large que Juliet. Des chiffres identiques sur les cinq auraient été le signe que quelque chose clochait dans la méthodologie, pas dans l'outil — un tel écart, avec une cause identifiée, est à quoi ressemble un benchmark honnête.
OWASP Benchmark Java, détail par catégorie
Le run indépendant le plus vaste et le plus dur — 2 740 cas, zéro faux négatif sur chacune des 11 catégories, mais une précision qui varie fortement selon la catégorie. Du pire au meilleur :
| Catégorie | Précision | Recall |
|---|---|---|
| Injection XPath | 42.9% | 100.0% |
| Injection LDAP | 45.8% | 100.0% |
| Injection de commandes | 50.2% | 100.0% |
| Injection SQL | 55.4% | 100.0% |
| Violation de frontière de confiance | 65.9% | 100.0% |
| Traversée de chemin | 79.6% | 100.0% |
| Hachage faible | 79.6% | 100.0% |
| Cryptographie faible | 100.0% | 100.0% |
| Aléatoire faible | 100.0% | 100.0% |
| XSS | 100.0% | 100.0% |
| Cookie non sécurisé | 100.0% | 100.0% |
Lecture honnête : le recall est parfait partout (chaque vulnérabilité plantée est détectée, dans chaque catégorie), mais quatre catégories riches en taint — injection XPath, injection LDAP, injection de commandes, injection SQL — se situent sous 56% de précision, ce qui signifie que le moteur de règles sur-détecte sur ces patterns spécifiques dans cette suite synthétique. Les vérifications de cryptographie faible, aléatoire faible, XSS et cookie non sécurisé sont exactes (100%/100%). C'est le vrai compromis actuel : réglé pour ne jamais manquer une vulnérabilité plantée, au prix de plus de faux positifs sur une poignée de catégories d'injection que nous le souhaiterions.
NIST Juliet Java, détail par catégorie
Le run le plus vaste de cette page — 6 616 cas sur les 6 catégories CWE pour lesquelles Juliet 1.3 fournit réellement des données (3 des 9 initialement prévues — XXE, aléatoire faible, validation de certificat, désérialisation — n'ont pas d'équivalent dans ce téléchargement NIST). Pire recall d'abord :
| Catégorie | Précision | Recall |
|---|---|---|
| Injection LDAP | 98.8% | 11.4% |
| Traversée de chemin (absolue) | 100.0% | 33.0% |
| Injection SQL | 98.4% | 41.9% |
| Traversée de chemin (relative) | 97.5% | 64.5% |
| Cryptographie faible | 100.0% | 89.5% |
| Injection de commandes | 98.3% | 99.4% |
La précision reste élevée partout (97,5–100%) — le moteur de règles crie rarement au loup — mais le recall varie énormément, et la raison est architecturale, pas aléatoire. Deux des douze variantes de source par catégorie chez Juliet (donnée lue via un appel base de données, ou passée via une « variante de flux » à méthode abstraite) vivent dans un fichier de classe compagnon que le scanner mono-fichier du benchmark ne voit jamais — ces cas sont inatteignables quelle que soit la qualité des règles, et tirent le plafond de chaque catégorie vers le bas. Dans ce qui est réellement atteignable, l'injection LDAP est le point faible actuel : les cas de test LDAP de Juliet s'appuient sur des patterns de source (lookups de contexte JNDI alimentés par des données de config/environnement) que ce jeu de règles ne reconnaît pas encore comme sources de taint, contrairement aux règles de traversée de chemin et d'injection SQL qui viennent d'être élargies. C'est un écart circonscrit et divulgué, pas caché.
Fixtures internes, détail par langage (auto-validation)
Le run interne de 910 cas, par langage — encore une fois : cela mesure la cohérence interne, pas la difficulté externe, puisque chaque cas est une fixture écrite pour une règle qui existe.
| Langage | Cas vulnérables | Détectés |
|---|---|---|
| Python | 144 | 144/144 |
| JavaScript/TypeScript | 84 | 84/84 |
| Java | 55 | 55/55 |
| HTML | 38 | 38/38 |
| YAML | 33 | 33/33 |
| PHP | 27 | 27/27 |
| C# | 25 | 25/25 |
| Autre (Dockerfile + générique) | 10 | 10/10 |
Suite de tests CVE, détail par framework
Le test le plus dur et le plus réaliste — 45 cas reconstruits à partir de vraies CVE publiées — détaillé honnêtement, y compris là où ça rate :
| Framework | Langage | Précision | Recall |
|---|---|---|---|
| Flask | Python | 100.0% | 100.0% |
| Django | Python | 100.0% | 100.0% |
| Spring | Java | 87.5% | 70.0% |
| Laravel | PHP | 100.0% | 66.7% |
| PHP stdlib | PHP | 80.0% | 66.7% |
| Python stdlib | Python | 100.0% | 66.7% |
| Express | JavaScript | 72.7% | 80.0% |
| ASP.NET | C# | 66.7% | 66.7% |
Point faible divulgué honnêtement : ASP.NET/C# et Express/JavaScript sont les plus bas de ce tableau — précision et recall entre 66 et 80%. Des CVE historiques du type chaînes de désérialisation façon log4shell ou chemins de taint multi-sauts complexes dans ces frameworks sont précisément les cas que le moteur de règles rate encore (les 11 faux négatifs incluent CVE-2021-44228 lui-même, suivi comme un écart ouvert, pas caché).
Ce que cette page n'inclut délibérément pas
- HTML, YAML et Dockerfile ne figurent dans aucun tableau ci-dessus. Ce ne sont pas des classes de vulnérabilité par injection façon CWE comme le sont l'injection SQL ou le XSS — les règles YAML ciblent les erreurs de configuration de pipeline CI/CD et les règles Dockerfile sont des vérifications d'hygiène (utilisateur root, image de base non épinglée), architecturalement différentes d'un benchmark précision/recall construit autour de vulnérabilités implantées. Voir le guide scan CI/CD pour ce qui y est réellement détecté.
- Les suites NIST Juliet C/C++ et .NET/C# existent et pourraient étendre cette page à d'autres langages — pas encore intégrées. Juliet Java elle-même ne compte que 6 de ses 112 catégories CWE mappées ici (voir ci-dessus) ; étendre la couverture aux 103 autres (dont beaucoup sans règle équivalente du tout, ex. dépassement d'entier, condition de course) est un travail futur, pas un résultat caché.
Pourquoi il n'y a aucun score concurrent sur cette page
Nous avons cherché. Des chiffres OWASP Benchmark publics existent pour certains concurrents, mais sourcés depuis le contenu marketing d'un éditeur concurrent, et une seconde source trouvée pour le même outil rapporte un chiffre sensiblement différent pour le même benchmark revendiqué — sans méthodologie, version de suite de test ni version d'outil divulguée pour aucune des deux. Ce n'est pas quelque chose que nous voulons répéter comme un fait. Si un concurrent publie un score de benchmark avec une méthodologie transparente et reproductible, nous le citerons, exactement comme le reste de cette page cite méthodologie et dates. En attendant, cette page compare StaticCodeAudit à la réalité, pas à des chiffres invérifiables sur d'autres outils.
Reproduire ces chiffres
Ces quatre méthodologies tournent via un outillage d'évaluation interne, séparé du code source du produit — NIST Juliet et OWASP Benchmark sont des suites de test tierces, pas du code que nous avons écrit, elles ne sont donc pas livrées avec l'outil. Ce n'est pas quelque chose que les utilisateurs finaux lancent au quotidien ; c'est le même outillage qui a produit les chiffres ci-dessus, exécuté contre le même moteur de règles.
run_benchmark.py owasp
run_benchmark.py owasp-python
run_benchmark.py cve
run_benchmark.py juliet
Chaque run exporte un fichier JSON daté avec le détail complet par catégorie — les tableaux de cette page sont retranscrits directement depuis ces exports, exécutés entre le 7 et le 9 août 2026 (les deux runs les plus vastes, OWASP Benchmark Java et NIST Juliet Java, ont duré respectivement 3 551 et 4 611 secondes — moins d'1h30 chacun — sur 2 740 et 6 616 cas).
Questions fréquentes
Pourquoi le score des fixtures internes affiche 100% alors que les deux autres non ?
Parce qu'il mesure autre chose. Les fixtures internes sont des cas de test appariés écrits spécifiquement pour chaque règle — une règle qui ne détecterait pas son propre cas de test conçu pour elle serait une règle cassée, pas un raté subtil. 100% ici signifie que le moteur de règles n'a pas de régression franche, pas que la détection est infaillible dans la vraie vie. OWASP Benchmark et la suite CVE sont indépendants du processus d'écriture des règles, d'où des chiffres plus bas et plus significatifs.
Une précision/recall de 66-80% sur certains frameworks de la suite CVE est-elle un problème ?
C'est une vraie limite, divulguée, pas quelque chose à enjoliver. Les flux de taint multi-sauts complexes et les gadgets de désérialisation spécifiques à un framework (le genre derrière CVE-2021-44228) sont réellement difficiles à capter de façon cohérente pour un analyseur statique à base de règles, commercial ou open source. Cette page existe précisément pour que cette limite soit visible plutôt qu'enterrée sous un seul chiffre en gros caractères gonflé.
Pourquoi la précision OWASP Benchmark Java n'est-elle que de 73,7% alors que le recall est un 100% parfait ?
Parce que le moteur de règles est actuellement réglé pour ne jamais manquer une vulnérabilité plantée, et cela a un coût : quatre catégories — injection XPath, injection LDAP, injection de commandes, injection SQL — se situent entre 43% et 55% de précision, ce qui signifie plus de faux positifs que souhaité sur ces patterns de taint spécifiques dans cette suite synthétique. Les sept autres catégories, dont XSS et la cryptographie faible, sont exactes. C'est une vraie limite actuelle, divulguée ici plutôt que lissée sous un score F1 agrégé.
OWASP Benchmark Java affiche 100% de recall mais NIST Juliet Java seulement 46,7% — même langage, CWE similaires. Lequel a raison ?
Les deux, pour ce que chacun mesure — et l'écart entre les deux est le vrai résultat. OWASP Benchmark est construit presque entièrement autour de patterns de source Servlet/HTTP ; Juliet sollicite aussi les variables d'environnement, les fichiers de propriétés, les sockets, l'entrée standard et les connexions URL comme sources de taint. Le moteur de règles avait été calibré vers le pattern qu'OWASP Benchmark récompense, et Juliet l'a exposé. Nous en avons déjà corrigé une partie — le recall sur Path Traversal et SQL Injection a globalement doublé ce cycle-ci après l'élargissement des sources de taint reconnues, avec une précision essentiellement inchangée (98,2% → 98,4%) — et les chiffres actuels de cette page reflètent ce correctif, pas ceux d'avant. L'injection LDAP est le prochain écart connu.
Voir la sortie de détection brute par vous-même
Ouvrez le rapport de démonstration en ligne — sans installation, sans inscription — et inspectez de vrais findings directement.
Ouvrir le rapport en ligne Voir les langages supportés