SV.SQL

Sql 注入

如果未经验证或受污染的数据直接用于 SQL 查询字符串,此错误将检测该情况。特别地,对于来自不同来源的用户输入(例如通过 J2EE servlet 发送的 HTTP 请求),直到将此数据用于 SQL 语句,此错误均可进行追踪。如果此数据未经检查便直接用于 java.sql.Statement.execute() 方法使用的 SQL,则攻击者可以将任意 SQL 语句输入此字符串。这将允许任意 SQL 命令直接从用户界面运行。

从 2023.2 版本开始,此检查器将支持 Jakarta EE。

漏洞与风险

SQL 注入会使数据库中的数据处于危险中。由于 SQL 语句中使用了未经验证的用户输入,攻击者可以注入他们希望执行的任何 SQL 语句。这包括删除、更新或创建数据。此外,也可能通过此类型的漏洞从数据库检索敏感数据。如果该命令用于身份验证,将导致未授权的访问。

Klocwork 安全漏洞 (SV) 检查器可识别可能创建危险数据的调用;这些调用被视为不安全的来源。用户所提供的任何数据都可能是不安全的来源,因为用户可能是攻击者,或者可能引入人为错误。

缓解与预防

通过验证来自应用程序外部的任何及所有输入(用户输入、文件输入、系统参数等),可预防 SQL 注入缺陷。验证应包括长度和内容。通常仅需要字母数字字符(即 A-Z、a-z、0-9)。应对任何其他接受的字符进行转义。应该在每个数据源处进行该验证,例如从 HTTP 请求读取每个参数时。此外,建议先检查用于 SQL 语句的所有字符串,然后再使用这些字符串。而且,此示例中使用的 SQL 语句同样有危险,因为其允许存在注入缺陷和其他可能造成危险的 SQL 执行。使用 SQL 预编译语句创建、更新和删除记录。

漏洞示例 1

复制
     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 在第 8 行报告 SV.SQL 缺陷,指出:accountNumber 包含来自 HTTP 请求参数的数据,因此可能已被污染(第 4 行)。此值与常量字符串连接,形成第 6 行的 query。第 8 行的 query 作为 SQL 语句执行。这可能被利用以注入任意 SQL 语句。

漏洞示例 2

复制
     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 在第 8 行报告 SV.SQL 缺陷,指出:accountNumber 包含来自 HTTP 请求参数的数据,因此可能已被污染(第 4 行)。此值与常量字符串连接,形成第 6 行的 query。第 8 行的 query 作为 SQL 语句执行。这可能被利用以注入任意 SQL 语句。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 Java 分析。