Ir al contenido principal

Java · SAST

SAST Java que se ejecuta totalmente sin conexión

Audite Spring Boot, JEE, Hibernate y JDBC contra vulnerabilidades OWASP Top 10, misconfiguraciones de framework y riesgos supply-chain — sin subir código a la nube.

Frameworks y librerías escaneados

Probamos la cobertura mediante fixtures en estos frameworks. Se añaden nuevos patrones en cada release de reglas integradas.

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

Principales clases CWE detectadas

Estas clases CWE aparecen con mayor frecuencia en bases de código modernas de este lenguaje. StaticCodeAudit incluye reglas dedicadas para cada una, mapeadas a OWASP Top 10 / ISO 27001 / ASVS cuando es pertinente.

CWE-89

Inyección SQL

Concatenación de strings en JDBC Statement, JPA createQuery con concat, MyBatis ${...} en lugar de #{...}, Hibernate HQL con string format.

Detectado por la regla SCA: sql_injection_concat_java

CWE-611

XML External Entity (XXE)

DocumentBuilderFactory, SAXParserFactory, XMLReader sin FEATURE_SECURE_PROCESSING ni DTD deshabilitado. Permite fuga de archivos y SSRF.

Detectado por la regla SCA: xxe_injection

CWE-502

Deserialización insegura

ObjectInputStream.readObject Java nativo sobre bytes no confiables (la clase « Java serialization gadget » que llevó a log4shell). Los payloads Apache Commons Collections siguen funcionando en 2026.

Detectado por la regla SCA: unsafe_deserialization

CWE-78

Inyección de comando OS

Runtime.getRuntime().exec(userString) con string shell, ProcessBuilder con concat. Ambos interpretan metacaracteres shell.

Detectado por la regla SCA: command_injection_java

CWE-798

Credenciales hardcoded

Credenciales en application.properties commiteado, claves AWS en application.yml, secreto firma JWT como constante String.

Detectado por la regla SCA: hardcoded_secret

CWE-22

Path Traversal

new File(userPath), Files.readAllBytes(Paths.get(userPath)) sin verificación de anclaje raíz — típico en endpoints de almacenamiento multi-tenant.

Detectado por la regla SCA: path_traversal_python

Vulnerable vs. seguro — tres ejemplos rápidos

CWE-89 Detectado por la regla SCA: sql_injection_concat_java
❌ Vulnerable
// Vulnerable — Statement concat
String sql = "SELECT * FROM users WHERE name = \'" + name + "\'";
ResultSet rs = stmt.executeQuery(sql);
✅ Seguro
// Seguro — PreparedStatement con bind
PreparedStatement ps = conn.prepareStatement(
    "SELECT * FROM users WHERE name = ?");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
CWE-611 Detectado por la regla SCA: xxe_injection
❌ Vulnerable
// Vulnerable — DocumentBuilderFactory por defecto
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().parse(input);
✅ Seguro
// Seguro — deshabilitar 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 Detectado por la regla SCA: command_injection_java
❌ Vulnerable
// Vulnerable — string shell
Runtime.getRuntime().exec("ping -c 1 " + userInput);
✅ Seguro
// Seguro — array de argumentos, sin interpretación shell
ProcessBuilder pb = new ProcessBuilder("ping", "-c", "1", userInput);
pb.start();

Qué detecta StaticCodeAudit (este lenguaje)

  • Inyección SQL en JDBC Statement, JPA, MyBatis, Hibernate HQL con concat
  • XXE en DocumentBuilderFactory, SAXParserFactory, XMLReader
  • Deserialización nativa Java sobre streams no confiables
  • Inyección de comando vía Runtime.exec, ProcessBuilder con string shell
  • Secretos hardcoded en application.properties, application.yml
  • Path traversal en new File, Files.readAllBytes sin anclaje raíz
  • Inyección LDAP en DirContext.search
  • Cookies inseguras (setSecure, setHttpOnly faltantes en Servlet API)
  • CSRF: Spring Security .csrf().disable() en config producción
  • Cripto insegura (MD5/SHA1 seguridad, DES, RC4, IV hardcoded)
  • JWT algoritmo none, secreto HS256 hardcoded
  • Sinks Log4j (detección patrón CVE-2021-44228)
  • APIs deprecadas (SSLv3, javax.xml.ws Endpoint, sun.misc.Unsafe)
  • Misconfiguraciones CI/CD (Maven/Gradle wrappers, tokens GitHub Actions)

¿Quiere saber cómo se mide realmente la calidad de detección? Consulte la metodología completa de benchmarks multilingües (OWASP Benchmark, NIST Juliet, precisión/recall/F1 por lenguaje) →

OWASP BenchmarkJava v1.2 — validación independiente

StaticCodeAudit fue medido contra el OWASP BenchmarkJava v1.2, una suite de pruebas pública y reproducible de 2.740 casos de test Java que cubre 11 categorías de vulnerabilidades.

98,8%
Puntuación F1
100%
Recall
2.740
Casos de test

9 de 11 categorías con F1 = 100%

99,8%
Inyección SQL
100%
XSS
100%
Inyección de comando
100%
Path Traversal
100%
Criptografía
100%
Aleatoriedad débil
100%
Inyección LDAP
100%
Trust Boundary
100%
Cookie segura
100%
Inyección XPath
≈89%
Hash

En total, 34 falsos positivos residuales: 33 en la categoría hash — MessageDigest.getInstance(algorithm) donde el string de algoritmo proviene de un archivo .properties externo, indistinguible estáticamente de una constante — más 1 en inyección SQL, ligado al análisis multiarchivo.

Las vulnerabilidades reales rara vez caben en un solo archivo

Las aplicaciones Spring dividen la lógica en capas: un controlador recibe la solicitud, un servicio construye la consulta. Un escáner limitado a un solo archivo a la vez nunca conecta ambos — ve el dato del usuario en Controller.java y la llamada a base de datos en Service.java, pero nunca la conexión entre ambos. StaticCodeAudit ahora sigue el dato a través de los archivos, igual que ya hace con 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 proviene de la solicitud HTTP en el controlador, y llega a la consulta SQL dos archivos después, sin modificar — StaticCodeAudit lo reporta en la línea exacta donde se ejecuta la consulta.

Audite su código

Audite Spring Boot, JEE, Hibernate y JDBC contra vulnerabilidades OWASP Top 10, misconfiguraciones de framework y riesgos supply-chain — sin subir código a la nube.

Descargar el binario demo Reservar una demo guiada