SV.SQL

Sql Injection

This error detects the situation when unvalidated or tainted data is used directly in an SQL query string. Specifically, this error traces user input from various sources, such as HTTP requests via J2EE servlets, to the use of this data in SQL statements. If this data is used, unchecked, directly in the SQL statement used in the java.sql.Statement.execute() method, then attackers can enter arbitrary SQL statements into this string. This allows arbitrary SQL commands to be run directly from the user interface.

As of release 2023.2, this checker supports Jakarta EE.

As of release 2026.3, this checker also treats LLM response text as an untrusted source.

Vulnerability and risk

SQL injections put data in the database at risk. Since unvalidated user input is being used in the SQL statement, an attacker can inject any SQL statement they wish to execute. This includes deleting, updating or creating data. It may also be possible to retrieve sensitive data from the database with this type of vulnerability. If the command is used for authentication, it will lead to unauthorized access.

Klocwork security vulnerability (SV) checkers identify calls that create potentially dangerous data; these calls are considered unsafe sources. An unsafe source can be any data provided by the user, since the user could be an attacker or has the potential for introducing human error.

Mitigation and prevention

Prevent SQL injection flaws by validating any and all input from outside the application (user input, file input, system parameters, etc.). Validation should include length and content. Typically only alphanumeric characters are needed (i.e., A-Za-z, 0-9). Any other accepted characters should be escaped. This validation should be done at each source of data, such as when each parameter is read from the HTTP request. Additionally it may be advisable to check all strings that are used in SQL statements before their use. Moreover, the use of SQL statements as in the sample is also dangerous, as it allows for injection flaws and other potentially dangerous SQL execution. Use SQL prepared statements for creating, updating and deleting records.

Vulnerable example 1

Copy
     import javax.servlet.http.*;
     public ResultSet getUserData(ServletRequest req, Connection con) throws SQLException {
         // Source of data from HTTP request in servlet
         String accountNumber = req.getParameter("accountNumber");
         // Use of string in SQL statement
         String query = "SELECT * FROM user_data WHERE userid = '" + accountNumber + "'";
         Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
         ResultSet results = statement.executeQuery(query);
         return results;
     }

Klocwork reports an SV.SQL defect for line 8, indicating: 'accountNumber' contains data coming from an HTTP request parameter and might be tainted (line 4). This value is concatenated with a constant string to form the 'query' on line 6. The 'query' is executed as an SQL statement on line 8. This can be exploited to inject arbitrary SQL statements.

Vulnerable example 2

Copy
     import jakarta.servlet.http.*;
     public ResultSet getUserData(ServletRequest req, Connection con) throws SQLException {
         // Source of data from HTTP request in servlet
         String accountNumber = req.getParameter("accountNumber");
         // Use of string in SQL statement
         String query = "SELECT * FROM user_data WHERE userid = '" + accountNumber + "'";
         Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
         ResultSet results = statement.executeQuery(query);
         return results;
     }

Klocwork reports an SV.SQL defect for line 8, indicating: 'accountNumber' contains data coming from an HTTP request parameter and might be tainted (line 4). This value is concatenated with a constant string to form the 'query' on line 6. The 'query' is executed as an SQL statement on line 8. This can be exploited to inject arbitrary SQL statements.

Vulnerable code example 3

Copy
import dev.langchain4j.model.chat.ChatModel;
import java.sql.SQLException;
import java.sql.Statement;

public class Example {
    public void run(Statement stmt, ChatModel model) throws SQLException {
        String table = model.chat("Which table holds the users?"); // untrusted LLM output
        stmt.executeQuery("select * from " + table); // concatenated into SQL
    }
}

Klocwork reports an SV.SQL defect on line 7 because LLM output is concatenated directly into an SQL query string before execution.

Fixed code example 3

Copy
import dev.langchain4j.model.chat.ChatModel;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Example {
    public void run(PreparedStatement ps, ChatModel model) throws SQLException {
        String value = model.chat("Which user?");
        ps.setString(1, value); // bound as a parameter, not concatenated into SQL
        ps.executeQuery();
    }
}

In this fixed example, Klocwork no longer reports an SV.SQL defect because the LLM output is bound as a parameter instead of being concatenated into the SQL statement.

Extension

This checker can be extended through the Klocwork knowledge base. See Tuning Java analysis for more information.