11 new issues in the Java analyzer

We have added 11 new issues, of which 7 issues are security issues:

JAVA-E1041 - Interface is unimplementable

This issue is raised when an interface declares certain methods which will prevent it from being compiled, or will cause a compiler error when the interface is implemented.

interface SomeInterface {
    int toString(); // This is a compile error.
    void wait(); // wait is final in object, it cannot be overridden.
    void clone(); // clone is protected in Object and will clash when this interface is implemented.
}

class SomeClass implements SomeInterface {
    @Override
    void clone() { // This method's signature will clash with the one defined in Object.
        return;
    }
}

JAVA-W1021 - Redundant type check

This issue is raised if the code checks whether a value is an instance of its super class, which is always true.

Integer a = 3;
// `a` is already a Number
if (a instanceof Number) {
    // ...
}

JAVA-W1022 - Multiple instanceof checks in an if-else ladder

This issue marks usages of if-else ladders that only have instanceof checks as conditions.

class FirstClass {}
class SecondClass extends FirstClass {}
class ThirdClass extends FirstClass {}

// Elsewhere...

Object someObj = new ThirdClass();

if (someObj instanceof FirstClass) { 
    // someObj will always only trigger the first if statement!
    System.out.println("first");
} else if (someObj instanceof SecondClass) {
    // ...
    System.out.println("second");
} else if (someObj instanceof ThirdClass) {
    // ...
    System.out.println("third");
} else {
    System.out.println("last");
}

JAVA-W1023 - Zip entries should not be empty

This issue is raised for instances where a new zip entry is created and immediately closed without any data being written.

ZipOutputStream zos = ...;
// ...
ZipEntry entry = new ZipEntry(...);
zos.putNextEntry(entry);
// No call to write!
zos.closeEntry();

Security Issues

The 7 following issues deal with security, covering OWASP 2021 categories A02, A03, A07, and A10. These issues cover various important security risks, such as web and SQL injection attacks as well as SSL and password generation-related vulnerabilities.

Note that issues marked as Audit are intended as softer warnings that may indicate possible risks to be aware of. These would require validation from the developer. You can read more about Audit issues here.

JAVA-S1033 - SMTP configurations should check SSL certificates for authenticity

This issue is raised when a JavaMail SMTP configuration attempts to use SSL but does not explicitly enable certificate validation as well.

Properties properties = PropertiesUtil.getSystemProperties();
properties.put("mail.transport.protocol", "smtp");
properties.put("mail.smtp.host", "some-hostname");
properties.put("mail.smtp.socketFactory.class", "some-class-name");
properties.put("mail.smtp.auth", "true");

// We do not set certificate validation to true via the mail.smtp.ssl.checkserveridentity property!

Authenticator authenticator = ...; // Create an authenticator implementation.
Session session = Session.getInstance(properties, authenticator);

JAVA-A1034 - Audit: User input should not directly be used in network calls

This issue is raised when a web request is performed to a URL obtained through external input.

HttpClient client = HttpClient.newHttpClient();
@Override
void doGet(HttpServletRequest request, HttpServletResponse response) {
    URI uri = new URI(request.getParameter("dest"));
    // uri is used directly without any validation here!
    HttpRequest r = HttpRequest.newBuilder(uri).build();
    client.send(r, ...);
    // ...
}

JAVA-A1035 - Audit: Including request data within HTML response strings may lead to XSS attacks

This issue is raised when data from a request is directly written to the body of a HTTP response.

String userName = req.getParameter("user");
String template = "<p>Hi, %s</p>";
String renderedPage = String.format(template, userName);

PrintWriter writer = resp.getWriter();

response.setStatus(200);
writer.print(renderedPage);
writer.flush();

JAVA-S1036 - Insecure RandomUtil implementations must not be used

This issue is raised when a RandomUtil class implementation generated by a vulnerable JHipster version is found in your codebase.

import org.apache.commons.lang3.RandomStringUtils;
/**
 * Utility class for generating random Strings.
 */
public final class RandomUtil {
    private static final int DEF_COUNT = 20;
    private RandomUtil() {
    }
    /**
     * Generate a password.
     *
     * @return the generated password.
     */
    public static String generatePassword() {
        return RandomStringUtils.randomAlphanumeric(DEF_COUNT); // This call is not using SecureRandom and will generate predictable passwords.
    }
    // ...
}

JAVA-A1040 - Audit: Hibernate query may be vulnerable to injection attacks

This issue is raised when a Hibernate query (either with Hibernate SQL or normal SQL through Hibernate) is made that allows external data to control the text of the query.

String userName = request.getParameter("name");
String password = request.getParameter("pass");

// An attacker could freely manipulate the value of userName or password to change the meaning of this query in some way.
List<LoginInfo> infoList = sessionFactory
    .getCurrentSession()
    .createQuery("from LoginInfo where userName='" + userName + "' and password='" + password + "'")
    .list();

JAVA-A1041 - Audit: Prepared query may be susceptible to injection attacks

This issue is raised when a prepared statement is created using Connection.prepareStatement(String) in a way that could be controlled by external data.

String user = request.getParameter("user");
String pass = request.getParameter("pass");
String predicate = request.getParameter("predicate");

// An attacker who could control the value of predicate here could make arbitrary changes to the query.
String query = "SELECT * FROM users WHERE " + predicate + " AND user = ? AND pass = ?";

// The tainted query is now used here!
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, user);
statement.setString(2, pass);

JAVA-A1042 - Audit: SQL query may be susceptible to injection attacks

This issue is raised when Connection.createStatement(String) is used with a string that may be controlled by external data.

String user = request.getParameter("user");
String pass = request.getParameter("pass");
String query = "SELECT * FROM users WHERE user = '" + user + "' AND pass = '" + pass + "'"; // Unsafe

Statement stmt = connection.createStatement(query); // This statement may be compromised!