SV.DATA.DB

此错误会检测那些将未验证的用户数据插入 SQL 数据库查询的情况。该数据直接从用户输入存储到数据库中,可能包含恶意内容。如果稍后在其他 SQL 语句中使用数据,则同样会产生 SQL 注入漏洞。如果稍后将数据用作 Web 接口的输出,那么也会产生跨站脚本漏洞。

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

漏洞与风险

数据注入漏洞使应用程序中可能存储恶意内容。如果直接将未检查的用户输入存入应用程序的数据库,则会产生漏洞。该数据可能包含恶意 HTML 内容、SQL 语句、受操纵的路径等,应用程序中稍后可能使用这些内容。例如,如果将该数据重新传递给 Web 接口,则数据注入会导致跨站脚本漏洞。

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

缓解与预防

可以通过验证所有来自应用程序外部的输入(例如用户输入、文件输入、系统参数等)防止数据注入缺陷。验证应包括长度和内容。在数据库中存储的所有数据都应该包括对特定类型(例如用户名)的词法检查。通常仅需要字母数字字符(即 A-Z、a-z、0-9)。应对任何其他接受的字符进行转义。应该在每个数据源处进行该验证,例如从 HTTP 请求读取每个参数时。此外,建议先检查用于 SQL 语句的所有字符串,然后再使用这些字符串。

示例 1

复制
     public void setUserLastName(ServletRequest req, Connection con) throws SQLException {
         // Source of data from HTTP request in servlet
         String lastName = req.getParameter("lastName");
         int userId = Integer.parseInt(req.getParameter("userId"));
 
         String query = "UPDATE userData INTO lastName=? WHERE userid = ?";
         PreparedStatement statement = con.prepareStatement(query);
         statement.setString(1, lastName);
         statement.setInt(2, userId);
         statement.executeUpdate();
     }

针对第 21 行报告 SV.DATA.DB:“lastName”包含来自 HTTP 请求的值,因此可能已被污染(第 14 行)。在第 19 行中,被污染的“lastName”用于创建 SQL 语句“statement”,该语句在第 21 行执行。

扩展

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