| name | Security Code Review |
| description | Identify security vulnerabilities and suggest secure coding practices |
Security Code Review Guidelines
When reviewing code for security issues, systematically check for common vulnerabilities and suggest secure alternatives.
OWASP Top 10 Focus Areas
1. Injection Attacks (SQL, NoSQL, Command, LDAP)
Look for:
- String concatenation in SQL queries
- Unsanitized user input in database queries
- Direct execution of user input
Vulnerable:
String query = "SELECT * FROM users WHERE username = '" + username + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
Runtime.getRuntime().exec("ping " + userInput);
Secure:
String query = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, username);
ResultSet rs = pstmt.executeQuery();
List<String> allowedHosts = Arrays.asList("localhost", "example.com");
if (allowedHosts.contains(userInput)) {
}
2. Broken Authentication
Look for:
- Passwords stored in plain text
- Weak password requirements
- Missing session timeout
- Predictable session IDs
- Missing multi-factor authentication
Vulnerable:
user.setPassword(password);
String sessionId = user.getId() + System.currentTimeMillis();
Secure:
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(password);
user.setPassword(hashedPassword);
String sessionId = UUID.randomUUID().toString();
3. Sensitive Data Exposure
Look for:
- Logging sensitive information
- Transmitting data over HTTP
- Storing secrets in code
- Returning detailed error messages
Vulnerable:
logger.info("User password: " + password);
String apiKey = "sk_live_1234567890abcdef";
catch (Exception e) {
return "Database error: " + e.getMessage();
}
Secure:
logger.info("User authenticated: " + username);
String apiKey = System.getenv("API_KEY");
catch (Exception e) {
logger.error("Database error", e);
return "An error occurred. Please try again later.";
}
4. XML External Entities (XXE)
Look for:
- XML parsers without XXE protection
- Processing untrusted XML data
Vulnerable:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(userProvidedXml);
Secure:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(userProvidedXml);
5. Broken Access Control
Look for:
- Missing authorization checks
- Insecure direct object references
- Path traversal vulnerabilities
- CORS misconfiguration
Vulnerable:
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userRepository.findById(id);
}
File file = new File("/uploads/" + filename);
Secure:
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id, Principal principal) {
User currentUser = getCurrentUser(principal);
if (!currentUser.canAccess(id)) {
throw new AccessDeniedException("Unauthorized");
}
return userRepository.findById(id);
}
Path basePath = Paths.get("/uploads").toAbsolutePath().normalize();
Path filePath = basePath.resolve(filename).normalize();
if (!filePath.startsWith(basePath)) {
throw new SecurityException("Invalid file path");
}
6. Security Misconfiguration
Look for:
- Debug mode in production
- Default credentials
- Unnecessary features enabled
- Missing security headers
- Verbose error messages
Vulnerable:
spring:
profiles:
active: dev
debug: true
Secure:
spring:
profiles:
active: prod
debug: false
server:
servlet:
session:
cookie:
secure: true
http-only: true
7. Cross-Site Scripting (XSS)
Look for:
- Unescaped user input in HTML
- innerHTML usage with user data
- Dangerous template rendering
Vulnerable:
document.getElementById('greeting').innerHTML =
"Hello " + userInput;
element.innerHTML = location.hash.substring(1);
Secure:
document.getElementById('greeting').textContent =
"Hello " + userInput;
const div = document.createElement('div');
div.textContent = userInput;
element.appendChild(div);
8. Insecure Deserialization
Look for:
- Deserializing untrusted data
- Using vulnerable serialization libraries
Vulnerable:
ObjectInputStream ois = new ObjectInputStream(userInputStream);
Object obj = ois.readObject();
Secure:
ObjectMapper mapper = new ObjectMapper();
MyObject obj = mapper.readValue(jsonString, MyObject.class);
ObjectInputStream ois = new ObjectInputStream(userInputStream) {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
if (!desc.getName().equals("com.example.SafeClass")) {
throw new InvalidClassException("Unauthorized deserialization");
}
return super.resolveClass(desc);
}
};
9. Using Components with Known Vulnerabilities
Look for:
- Outdated dependencies
- Unpatched libraries
- Dependencies with security advisories
Check:
mvn versions:display-dependency-updates
mvn dependency-check:check
npm audit
pip-audit
Recommendation:
- Keep dependencies updated
- Monitor security advisories
- Use dependency scanning tools in CI/CD
- Remove unused dependencies
10. Insufficient Logging and Monitoring
Look for:
- No audit logs for security events
- Missing failed login tracking
- No alerting for suspicious activity
Vulnerable:
@PostMapping("/login")
public void login(String username, String password) {
if (authenticate(username, password)) {
}
}
Secure:
@PostMapping("/login")
public void login(String username, String password, HttpServletRequest request) {
boolean success = authenticate(username, password);
if (success) {
auditLog.info("Successful login: user={}, ip={}",
username, request.getRemoteAddr());
} else {
auditLog.warn("Failed login attempt: user={}, ip={}",
username, request.getRemoteAddr());
failedLoginTracker.record(username, request.getRemoteAddr());
}
}
Additional Security Checks
Cryptography
Look for:
- Use of weak algorithms (MD5, SHA1, DES)
- Hardcoded encryption keys
- Missing initialization vectors
- Weak random number generators
Vulnerable:
MessageDigest md = MessageDigest.getInstance("MD5");
Random random = new Random();
byte[] key = "hardcodedkey1234".getBytes();
Secure:
MessageDigest md = MessageDigest.getInstance("SHA-256");
SecureRandom random = new SecureRandom();
byte[] key = loadKeyFromSecureStorage();
API Security
Look for:
- Missing rate limiting
- No API authentication
- Excessive data exposure
- Missing input validation
Secure Practices:
@RestController
@RequestMapping("/api/v1")
public class UserController {
@RateLimiter(name = "userApi")
@GetMapping("/users")
public Page<UserDto> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
Principal principal) {
if (size > 100) {
throw new IllegalArgumentException("Page size too large");
}
return userService.findAll(page, size)
.map(this::toDto);
}
}
Security Review Checklist
When reviewing code, check:
Reporting Security Issues
When documenting security findings:
### [CRITICAL] SQL Injection in User Search
**Location**: UserController.java:45
**Issue**: User input is concatenated directly into SQL query, allowing SQL injection attacks.
**Vulnerable Code**:
```java
String query = "SELECT * FROM users WHERE name LIKE '%" + searchTerm + "%'";
Impact: Attackers can execute arbitrary SQL, potentially accessing all database data or modifying records.
Recommendation: Use parameterized queries with PreparedStatement.
Fixed Code:
String query = "SELECT * FROM users WHERE name LIKE ?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, "%" + searchTerm + "%");
Severity: Critical
CVSS Score: 9.8 (Critical)
Remediation Priority: Immediate
## When This Skill Activates
This skill automatically activates when:
- Reviewing code for security vulnerabilities
- Performing security audits
- Analyzing authentication/authorization code
- Checking for OWASP Top 10 vulnerabilities
- Questions about secure coding practices
- Reviewing API security
- Analyzing cryptographic implementations