Free Java SAST scanner: find security bugs in Java code

DepWarden's free Java SAST scanner checks Java source code against 74 security rules (including 6 Spring-specific, 10 Android-specific rules). Every rule maps to a CWE and the findings span 8 OWASP Top 10 categories, and every finding comes with an explanation, a fix and a before-and-after example. Paste a file, upload a zip or connect a repository: no account, and the results stay in a private, session-isolated workspace.

Java runs a large share of enterprise back ends, from Spring Boot services to Jakarta EE applications, and Android apps. Long-lived codebases accumulate old patterns: SQL built by concatenation, weak hashes and unsafe deserialization.

What DepWarden checks in Java code

74 rules cover 47 distinct weakness types (19 critical, 35 high, 15 medium and 5 low severity).

What it checksRulesExamples
Weak cryptography21Android HostnameVerifier always returns true; Android TrustManager trusts all certificates; MD5 used for password hashing
Injection (SQL, command, code)17Groovy shell / script engine injection; JNDI lookup from untrusted input (Log4Shell vector); OGNL expression evaluated from untrusted input
Insecure configuration10CORS: Access-Control-Allow-Credentials with wildcard origin; Spring Boot all actuator endpoints exposed; Spring Boot SSL disabled
Privacy and data leaks5Android Log statement with sensitive data; Android sensitive data stored on external storage; Android SharedPreferences in world-readable mode
Authentication and sessions3JWT none algorithm accepted; JWT signed or accepted with SignatureAlgorithm.NONE; Token or secret compared with non-constant-time equality
Hardcoded secrets3Hardcoded symmetric encryption key; JWT signed with weak or hardcoded secret; API key or token in URL query string
Insecure deserialization3Insecure Java deserialization; Jackson default typing enables polymorphic deserialization RCE; XStream.fromXML on untrusted input
Path traversal3Android WebView file:// access enabled; Path traversal via request parameter; Zip Slip — zip entry extracted without path validation
Reliability and error handling3Empty catch block silently suppresses exceptions; System.exit() called in library/service code; Thread.sleep used for timing logic
Server-side request forgery2SSRF — HTTP request to user-controlled URL; SSRF via Apache HttpClient / OkHttp with untrusted URL
Access control1Spring open redirect via user-supplied URL
Cross-site request forgery1Spring Security CSRF protection disabled
Cross-site scripting1Android WebView JavaScript enabled
File handling1File upload without type or size restriction

Examples from the Java rules

OS command injection (CWE-78, critical)

Runtime.exec / ProcessBuilder runs a command assembled from untrusted input.

Vulnerable:

Runtime.getRuntime().exec("convert " + filename + " out.png");

Fixed:

new ProcessBuilder("convert", filename, "out.png").start();

Pass arguments as a String[] (not a single concatenated command), validate against an allowlist, and avoid invoking a shell.

Jackson default typing enables polymorphic deserialization RCE (CWE-502, critical)

ObjectMapper.enableDefaultTyping()/activateDefaultTyping() lets the JSON payload specify the Java class to instantiate during deserialization, enabling remote code execution via gadget chains.

Vulnerable:

mapper.enableDefaultTyping();

Fixed:

// Use @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) with an explicit @JsonSubTypes allowlist instead

Remove default typing. If polymorphic deserialization is required, use @JsonTypeInfo with an explicit @JsonSubTypes allowlist instead.

JWT signed or accepted with SignatureAlgorithm.NONE (CWE-347, critical)

Signing or accepting JWTs with SignatureAlgorithm.NONE means the token has no signature — anyone can forge a valid-looking token for any subject.

Vulnerable:

Jwts.builder().setSubject(userId).signWith(SignatureAlgorithm.NONE).compact();

Fixed:

Jwts.builder().setSubject(userId).signWith(SignatureAlgorithm.RS256, privateKey).compact();

Use a strong algorithm (RS256/ES256) and always verify the signature; never allow NONE.

Run it

- uses: Rushabh5000/depwarden-action@v1
  with:
    sast-dir: src
    sast-fail-on: high
  env:
    APP_API_KEY: ${{ secrets.APP_API_KEY }}

What it does not do

DepWarden's SAST engine uses pattern rules and taint-aware rules that require untrusted input to reach a dangerous call. It is not a full cross-file dataflow engine, so a bug that only appears when data crosses several files can be missed, and every static analyser reports some false positives. Treat findings as leads: review them, fix the real ones and suppress the rest with a written reason. SAST covers the code you write; for the packages you import, run software composition analysis too.

Frequently asked questions

Is there a free Java SAST tool?

Yes. DepWarden's Java scanner is free in the browser with no account: paste code, upload a zip or connect a repository. Running SAST from CI through an API key needs a plan that includes SAST.

Which Java files are scanned?

.java. Configuration and secret-bearing files such as .env and key files are also checked for hardcoded credentials, whatever language the project uses.

How do I fix what it finds?

Each finding names the weakness (CWE), explains why the code is risky, shows a vulnerable and a fixed version of the pattern, and gives the remediation. Fix the code, then scan again to confirm the finding is gone.

More

Other languages: Python, JavaScript and TypeScript, PHP, Go (Golang), C#, Ruby, Kotlin, Swift, and secret scanning. Compare the options in free SAST tools compared, or start with what is SAST and SAST vs SCA.