mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-06 19:35:13 +02:00
* chore: Exclude CLAUDE.md from Cargo.toml * feat: add callgraph module and integrate into main analysis flow * feat: enhance CLI with new severity filtering and analysis modes * feat: update CHANGELOG with recent enhancements and fixes to severity filtering and output handling * feat: implement state-model dataflow analysis for resource lifecycle and auth state * feat: enhance diagnostic output formatting and add evidence structure * feat: implement attack surface ranking for diagnostics with scoring and sorting * feat: add comprehensive documentation for installation, usage, and rules reference * feat: add multiple language support for command execution and evaluation endpoints * feat: implement inline suppression for findings using `nyx:ignore` comments * feat: add confidence levels to AST patterns and update output structure * feat: implement low-noise prioritization system with category filtering, rollup grouping, and configurable budgets * feat: bump version to 0.4.0 and update changelog with new features and improvements * feat: add dead code allowances to various functions in mod.rs and real_world_tests.rs
3.8 KiB
3.8 KiB
Java Rules
Nyx detects Java vulnerabilities through AST patterns and taint analysis, covering deserialization, command execution, reflection, SQL injection, weak crypto, and XSS.
Taint Labels
Java has moderate taint label coverage. Sources, sinks, and sanitizers are defined in src/labels/java.rs.
Sources
| Matcher | Cap |
|---|---|
System.getenv |
all |
getParameter, getInputStream, getHeader, getCookies, getReader, getQueryString, getPathInfo |
all |
readObject, readLine |
all |
Sanitizers
| Matcher | Cap |
|---|---|
HtmlUtils.htmlEscape, StringEscapeUtils.escapeHtml4 |
HTML_ESCAPE |
Sinks
| Matcher | Cap |
|---|---|
Runtime.exec, ProcessBuilder |
SHELL_ESCAPE |
executeQuery, executeUpdate, prepareStatement |
SHELL_ESCAPE |
Class.forName |
SHELL_ESCAPE |
println, print, write |
HTML_ESCAPE |
AST Pattern Rules
Deserialization
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
java.deser.readobject |
High | A | ObjectInputStream.readObject() — unsafe deserialization |
Command Execution
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
java.cmdi.runtime_exec |
High | A | Runtime.getRuntime().exec() — shell command execution |
Reflection
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
java.reflection.class_forname |
Medium | A | Class.forName() — dynamic class loading |
java.reflection.method_invoke |
Medium | A | Method.invoke() — reflective method invocation |
SQL Injection
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
java.sqli.execute_concat |
Medium | B | SQL execute*() with concatenated string argument |
Weak Crypto
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
java.crypto.insecure_random |
Low | A | new Random() — java.util.Random is not cryptographically secure |
java.crypto.weak_digest |
Low | A | MessageDigest.getInstance("MD5"/"SHA1") |
XSS
| Rule ID | Severity | Tier | Description |
|---|---|---|---|
java.xss.getwriter_print |
Medium | A | response.getWriter().print/println/write — direct output |
Examples
java.deser.readobject — Unsafe deserialization
Vulnerable:
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
Object obj = ois.readObject(); // Arbitrary object instantiation
Safe alternative:
// Use a safe format like JSON
ObjectMapper mapper = new ObjectMapper();
MyType obj = mapper.readValue(request.getInputStream(), MyType.class);
java.sqli.execute_concat — SQL concatenation
Vulnerable:
String query = "SELECT * FROM users WHERE id=" + userId;
stmt.executeQuery(query); // SQL injection
Safe alternative:
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?");
ps.setString(1, userId);
ResultSet rs = ps.executeQuery();
java.cmdi.runtime_exec — Command execution
Vulnerable:
Runtime.getRuntime().exec("cmd /c " + userCommand);
Safe alternative:
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "dir");
// Use explicit argument list, never concatenate user input
java.reflection.class_forname — Dynamic class loading
Flagged:
Class<?> cls = Class.forName(className);
Object obj = cls.getDeclaredConstructor().newInstance();
Safe alternative:
// Use an allowlist of permitted class names
Map<String, Class<?>> allowed = Map.of("User", User.class, "Order", Order.class);
Class<?> cls = allowed.get(className);
if (cls != null) { /* ... */ }