Frameworks / libraries / dependencies The check for outdated and vulnerable frameworks, libraries and dependencies is a good starting point for every code review. Not only are these possible vulnerabilities easy to spot, but it also gets you a good introduction and basic understanding of the code you are looking at. You can use Mitres CVE list (https://cve.mitre.org/cve/search_cve_list.html) or Exploit-DB (https://www.exploit-db.com/) to find vulnerable software versions. You can also use tools like snyk or Nessus for automated scanning.
Input Validation: Check whether input data from untrusted sources is properly validated in the Java code. Look for methods like
String.split()
,Runtime.exec()
,ProcessBuilder.command()
, etc. that may be susceptible to command injection attacks.
public void executeCommand(String command) {
Runtime.getRuntime().exec(command);
}
In this example, the executeCommand
method takes a string argument that is directly passed to the Runtime.getRuntime().exec()
method. An attacker can inject malicious code through this method by passing in a command containing special characters. To prevent command injection attacks, the command
argument should be validated and sanitized before it is passed to the exec()
method.
A more secure version of the executeCommand
method could look like this:
public void executeCommand(String command) { if (isValidCommand(command)) { Runtime.getRuntime().exec(command); } else { throw new IllegalArgumentException("Invalid command"); } } private boolean isValidCommand(String command) {
// Validate the command string
// For example, check that it only contains alphanumeric characters and a whitelist of allowed special characters
}
Authentication and Authorization: Verify that the authentication and authorization mechanisms implemented in the Java code are secure and cannot be bypassed. Check if the user inputs are properly sanitized and validated.
Encryption and Decryption: Check that sensitive data is properly encrypted in transit and at rest. Look for uses of encryption algorithms that have known weaknesses and that are susceptible to attack.
Error Handling: Verify that error messages do not reveal too much information or provide clues to potential attackers. Make sure that error messages are not used to bypass the application’s security controls. If error messages are not handled properly and get passed directly to the user, an attacker could use this to get sensitive information.
Session Management: Check that session management is secure and prevents unauthorized access. Look for use of secure session management techniques, such as the use of unique and random session IDs and session timeouts. You can validate the quality of randomness of your tokens and IDs for with Burp Suits Sequencer module.
SQL Injection: Check for any code that constructs SQL statements dynamically, and verify that user input is properly validated and sanitized to prevent SQL injection attacks.
public void getUserData(String username, String password) {
String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
ResultSet result = executeQuery(query);
// process the result set
}
In this example, the getUserData
method takes two string arguments (username
and password
) that are directly used to construct a SQL query. An attacker could inject malicious SQL code through these arguments. To prevent SQL injection attacks, these input values should be validated and sanitized before they are used to construct the query.
A more secure version of the getUserData
method using prepared statements could look like this:
public void getUserData(String username, String password) {
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, username);
statement.setString(2, password);
ResultSet result = statement.executeQuery();
// process the result set
}
- Cross-Site Scripting (XSS): Verify that the Java code is properly validating and sanitizing all user input to prevent XSS attacks.
public void displayMessage(String message) {
String output = "<p>" + message + "</p>";
response.getWriter().write(output);
}
In this example, the displayMessage
method takes a string argument (message
) that is directly used to construct an HTML output. An attacker can inject malicious script code through this argument. To prevent XSS attacks, the input value should be validated and sanitized before it is used to construct the HTML output.
A more secure version of the displayMessage
method could look like this:
public void displayMessage(String message) {
String output = "<p>" + sanitize(message) + "</p>";
response.getWriter().write(output);
}
private String sanitize(String input) {
// Validate and sanitize the input string
// For example, replace < with < and > with >
}
In this version, the sanitize
method is called to validate and sanitize the input value before it is used to construct the HTML output. But always make shure your input validation is not only performed by the client, but by the server as well.
In addition you could use an “allow list” approach, if your application logic allows that. This could be done with dropdown menus or Regex pattern matching.
Cross-Site Request Forgery (CSRF): Verify that the Java code is properly validating and checking for CSRF tokens to prevent CSRF attacks.
File Inclusion: Check for any file inclusion vulnerabilities in the Java code. Look for any use of user input to construct file paths, and verify that user input is properly sanitized and validated.