Aller au contenu principal

Java · SAST

SAST Java qui tourne entièrement hors-ligne

Auditez Spring Boot, JEE, Hibernate et JDBC contre les vulnérabilités OWASP Top 10, misconfigurations de framework et risques supply-chain — sans téléverser de code dans le cloud.

Frameworks & bibliothèques scannés

Nous testons la couverture sur ces frameworks via fixtures. De nouveaux patterns sont ajoutés à chaque release de règles builtin.

Spring Boot Spring MVC Spring Security JEE Jakarta EE Hibernate JPA MyBatis JDBC Apache Struts JSF Jersey Apache Commons Jackson log4j slf4j BouncyCastle

Principales classes CWE détectées

Ces classes CWE apparaissent le plus souvent dans les codebases modernes de ce langage. StaticCodeAudit livre des règles dédiées pour chacune, mappées à OWASP Top 10 / ISO 27001 / ASVS quand pertinent.

CWE-89

Injection SQL

Concaténation de strings en JDBC Statement, JPA createQuery avec concat, MyBatis ${...} au lieu de #{...}, Hibernate HQL avec format de string.

Détecté par la règle SCA : sql_injection_concat_java

CWE-611

XML External Entity (XXE)

DocumentBuilderFactory, SAXParserFactory, XMLReader sans FEATURE_SECURE_PROCESSING ni DTD désactivé. Permet fuite de fichiers et SSRF.

Détecté par la règle SCA : xxe_injection

CWE-502

Désérialisation non sécurisée

ObjectInputStream.readObject Java natif sur bytes non fiables (la classe « Java serialization gadget » qui a mené à log4shell). Les payloads Apache Commons Collections fonctionnent encore en 2026.

Détecté par la règle SCA : unsafe_deserialization

CWE-78

Injection de commande OS

Runtime.getRuntime().exec(userString) avec string shell, ProcessBuilder avec concat. Les deux interprètent les métacaractères shell.

Détecté par la règle SCA : command_injection_java

CWE-798

Identifiants en dur

Identifiants dans application.properties committé, clés AWS dans application.yml, secret de signature JWT en constante String.

Détecté par la règle SCA : hardcoded_secret

CWE-22

Path Traversal

new File(userPath), Files.readAllBytes(Paths.get(userPath)) sans contrôle d'ancrage racine — typique avec endpoints de stockage de fichiers multi-tenant.

Détecté par la règle SCA : path_traversal_python

Vulnérable vs. sain — trois exemples rapides

CWE-89 Détecté par la règle SCA : sql_injection_concat_java
❌ Vulnérable
// Vulnérable — Statement concat
String sql = "SELECT * FROM users WHERE name = \'" + name + "\'";
ResultSet rs = stmt.executeQuery(sql);
✅ Sain
// Sain — PreparedStatement avec bind
PreparedStatement ps = conn.prepareStatement(
    "SELECT * FROM users WHERE name = ?");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
CWE-611 Détecté par la règle SCA : xxe_injection
❌ Vulnérable
// Vulnérable — DocumentBuilderFactory par défaut
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().parse(input);
✅ Sain
// Sain — désactiver DTD + secure processing
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
Document doc = dbf.newDocumentBuilder().parse(input);
CWE-78 Détecté par la règle SCA : command_injection_java
❌ Vulnérable
// Vulnérable — string shell
Runtime.getRuntime().exec("ping -c 1 " + userInput);
✅ Sain
// Sain — array d'arguments, pas d'interprétation shell
ProcessBuilder pb = new ProcessBuilder("ping", "-c", "1", userInput);
pb.start();

Ce que StaticCodeAudit détecte (ce langage)

  • Injection SQL en JDBC Statement, JPA, MyBatis, Hibernate HQL avec concat
  • XXE dans DocumentBuilderFactory, SAXParserFactory, XMLReader
  • Désérialisation native Java sur streams non fiables
  • Injection de commande via Runtime.exec, ProcessBuilder avec string shell
  • Secrets en dur dans application.properties, application.yml
  • Path traversal dans new File, Files.readAllBytes sans ancrage racine
  • Injection LDAP dans DirContext.search
  • Cookies non sécurisés (setSecure, setHttpOnly manquants en Servlet API)
  • CSRF : Spring Security .csrf().disable() en config production
  • Crypto non sécurisée (MD5/SHA1 sécurité, DES, RC4, IV en dur)
  • JWT algorithme none, secret HS256 en dur
  • Sinks Log4j (détection pattern CVE-2021-44228)
  • APIs dépréciées (SSLv3, javax.xml.ws Endpoint, sun.misc.Unsafe)
  • Misconfigurations CI/CD (Maven/Gradle wrappers, tokens GitHub Actions)

Envie de savoir comment la qualité de détection est réellement mesurée ? Consultez la méthodologie complète des benchmarks multi-langages (OWASP Benchmark, NIST Juliet, précision/recall/F1 par langage) →

OWASP BenchmarkJava v1.2 — validation indépendante

StaticCodeAudit a été mesuré sur l'OWASP BenchmarkJava v1.2, un benchmark public et reproductible de 2 740 cas de test Java couvrant 11 catégories de vulnérabilités.

98,8 %
Score F1
100 %
Rappel
2 740
Cas de test

9 catégories sur 11 à F1 = 100 %

99,8 %
Injection SQL
100 %
XSS
100 %
Injection de commande
100 %
Path Traversal
100 %
Cryptographie
100 %
Aléatoire faible
100 %
Injection LDAP
100 %
Trust Boundary
100 %
Cookie sécurisé
100 %
Injection XPath
≈89 %
Hash

34 faux positifs résiduels sur l'ensemble du benchmark : 33 sur la catégorie hash — MessageDigest.getInstance(algorithm) où la chaîne d'algorithme provient d'un fichier .properties externe, indiscernable statiquement d'une constante — plus 1 sur l'injection SQL, lié à l'analyse multi-fichiers.

Les vraies failles tiennent rarement dans un seul fichier

Les applications Spring répartissent la logique en couches : un contrôleur reçoit la requête, un service construit la requête SQL. Un scanner limité à un seul fichier à la fois ne fait jamais le lien — il voit la donnée utilisateur dans Controller.java et l'appel base de données dans Service.java, mais jamais la connexion entre les deux. StaticCodeAudit suit désormais la donnée à travers les fichiers, comme il le fait déjà pour Python.

Controller.java
@GetMapping("/orders")
public String findOrder(@RequestParam String id, Model model) {
    model.addAttribute("order", orderService.findOrder(id));
    return "order-view";
}
Service.java
public Order findOrder(String id) {
    String sql = "SELECT * FROM orders WHERE id = " + id;
    return jdbcTemplate.queryForObject(sql, Order.class);
}

id provient de la requête HTTP dans le contrôleur, et atteint la requête SQL deux fichiers plus loin, sans modification — StaticCodeAudit le signale à la ligne exacte où la requête s'exécute.

Auditez votre code

Auditez Spring Boot, JEE, Hibernate et JDBC contre les vulnérabilités OWASP Top 10, misconfigurations de framework et risques supply-chain — sans téléverser de code dans le cloud.

Télécharger le binaire démo Réserver une démo guidée