Skip to main content

Java · SAST

Java SAST that runs entirely offline

Audit Spring Boot, JEE, Hibernate and plain JDBC for OWASP Top 10 vulnerabilities, framework misconfigurations and supply-chain risks — all without uploading code to the cloud.

Frameworks & libraries scanned

We test fixture coverage on these frameworks. New patterns are added with each builtin rule release.

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

Top CWE classes detected

These CWE classes appear most often in modern codebases of this language. StaticCodeAudit ships dedicated rules for each, mapped to OWASP Top 10 / ISO 27001 / ASVS where relevant.

CWE-89

SQL Injection

String concatenation in JDBC Statement, JPA createQuery with concat, MyBatis ${...} instead of #{...}, Hibernate HQL with string format.

Detected by SCA rule: sql_injection_concat_java

CWE-611

XML External Entity (XXE)

DocumentBuilderFactory, SAXParserFactory, XMLReader without FEATURE_SECURE_PROCESSING or DTD disabled. Allows file disclosure and SSRF.

Detected by SCA rule: xxe_injection

CWE-502

Insecure Deserialization

Java native ObjectInputStream.readObject on untrusted bytes (the « Java serialization gadget » class of bugs that led to log4shell). Apache Commons Collections payloads still work in 2026.

Detected by SCA rule: unsafe_deserialization

CWE-78

OS Command Injection

Runtime.getRuntime().exec(userString) with shell string, ProcessBuilder with concat. Both interpret the shell metacharacters.

Detected by SCA rule: command_injection_java

CWE-798

Hardcoded Credentials

Credentials in application.properties committed, AWS keys in application.yml, JWT signing secret as constant String.

Detected by SCA rule: hardcoded_secret

CWE-22

Path Traversal

new File(userPath), Files.readAllBytes(Paths.get(userPath)) without root anchor check — typical with multi-tenant file storage endpoints.

Detected by SCA rule: path_traversal_python

Vulnerable vs. clean — three quick examples

CWE-89 Detected by SCA rule: sql_injection_concat_java
❌ Vulnerable
// Vulnerable — Statement concat
String sql = "SELECT * FROM users WHERE name = \'" + name + "\'";
ResultSet rs = stmt.executeQuery(sql);
✅ Clean / safe
// Clean — PreparedStatement with bind
PreparedStatement ps = conn.prepareStatement(
    "SELECT * FROM users WHERE name = ?");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
CWE-611 Detected by SCA rule: xxe_injection
❌ Vulnerable
// Vulnerable — default DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().parse(input);
✅ Clean / safe
// Clean — disable 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 Detected by SCA rule: command_injection_java
❌ Vulnerable
// Vulnerable — shell string
Runtime.getRuntime().exec("ping -c 1 " + userInput);
✅ Clean / safe
// Clean — argument array, no shell interpretation
ProcessBuilder pb = new ProcessBuilder("ping", "-c", "1", userInput);
pb.start();

What StaticCodeAudit detects (this language)

  • SQL injection in JDBC Statement, JPA, MyBatis, Hibernate HQL with concat
  • XXE in DocumentBuilderFactory, SAXParserFactory, XMLReader
  • Java native deserialization on untrusted streams
  • Command injection via Runtime.exec, ProcessBuilder with shell string
  • Hardcoded secrets in application.properties, application.yml
  • Path traversal in new File, Files.readAllBytes without root anchor
  • LDAP injection in DirContext.search
  • Insecure cookies (setSecure, setHttpOnly missing in Servlet API)
  • CSRF: Spring Security .csrf().disable() in production config
  • Insecure crypto (MD5/SHA1 for security, DES, RC4, hardcoded IV)
  • JWT none algorithm, hardcoded HS256 secret
  • Log4j tagged sinks (CVE-2021-44228 pattern detection)
  • Deprecated APIs (SSLv3, javax.xml.ws Endpoint, sun.misc.Unsafe)
  • CI/CD misconfigurations (Maven/Gradle wrappers, GitHub Actions tokens)

Curious how detection quality is actually measured? See the full cross-language benchmark methodology (OWASP Benchmark, NIST Juliet, precision/recall/F1 per language) →

OWASP BenchmarkJava v1.2 — independent validation

StaticCodeAudit was measured against OWASP BenchmarkJava v1.2, a public, reproducible test suite of 2,740 Java test cases across 11 vulnerability categories.

98.8%
F1 Score
100%
Recall
2,740
Test cases

9 of 11 categories at F1 = 100%

99.8%
SQL Injection
100%
XSS
100%
Command Injection
100%
Path Traversal
100%
Cryptography
100%
Weak Random
100%
LDAP Injection
100%
Trust Boundary
100%
Secure Cookie
100%
XPath Injection
≈89%
Hash

34 residual false positives across the full suite: 33 on the hash category — MessageDigest.getInstance(algorithm) where the algorithm string comes from an external .properties file, indistinguishable from a hardcoded constant by static analysis — plus 1 on SQL injection from the cross-file analysis path.

Real vulnerabilities rarely live in one file

Spring applications split logic across layers: a controller receives the request, a service builds the query. A scanner limited to one file at a time never connects the two — it sees user input in Controller.java and a database call in Service.java, but never the link between them. StaticCodeAudit now follows the data across files, the same way it already does for 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 comes from the HTTP request in the controller, and reaches the SQL query two files later, unmodified — StaticCodeAudit reports it at the exact line where the query runs.

Audit your codebase

Audit Spring Boot, JEE, Hibernate and plain JDBC for OWASP Top 10 vulnerabilities, framework misconfigurations and supply-chain risks — all without uploading code to the cloud.

Download demo binary Book a walkthrough