为什么 Veracode 会报告 CWE-89?

Why does Veracode report CWE-89?

提问人:Radek Chromík 提问时间:8/31/2020 更新时间:5/16/2023 访问量:1313

问:

我有这个用JDBC编写的SQL查询,其中包含动态表和字段名称:

    private String checkDimension(String tenantId, String prefix, Long schemaMetaId, Long transactionalMetaId,
                                  String dimension, String dimensionValue) {
        DataSource tenantDataSource = tenantDataSourceProvider.getTenantDataSource(checkEntityName(tenantId));
        try (Connection connection = tenantDataSource.getConnection()) {

            String sql = String.format("select * from \"%s_%s\" input_file join \"DIMENSION_VALUES_%s\" dv on " +
                            "(dv.\"DIMENSION\" = ? and dv.\"DIMENSION_VALUE\" = input_file.\"%s\") limit 1",
                    checkEntityName(prefix), checkEntityName(schemaMetaId.toString()),
                    checkEntityName(transactionalMetaId.toString()), checkEntityName(dimensionValue));
            try (PreparedStatement statement = connection.prepareStatement(sql)) {
                statement.setString(1, dimension);
                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        return "OK";
                    } else {
                        return "Values do not match";
                    }
                }
            }
        } catch (SQLException exception) {
            throw new IllegalStateException(exception);
        }
    }

对于缓解缺陷,我正在使用应该使它们静音的功能(在 Veracode 扫描期间使它们误报)checkEntityName

    @SQLQueryCleanser
    static String checkEntityName(String entityName) {
        if (!entityName.matches("^[-a-zA-Z0-9_]*$")) {
            throw new SecurityException(String.format("Invalid name for entity: %s", entityName));
        }
        return entityName;
    }

但 Veracode 仍在报告此问题:

缺陷 ID:1433

说明:此数据库查询包含 SQL 注入缺陷。对 java.sql.Statement.executeQuery() 的调用使用派生自不受信任输入的变量构造动态 SQL 查询。攻击者可利用此缺陷对数据库执行任意 SQL 查询。executeQuery() 的第一个参数包含来自变量 format() 的污染数据。受污染的数据源自之前对 java.sql.Statement.executeQuery 的调用。

修正:避免动态构造 SQL 查询。相反,请使用参数化的预准备语句来防止数据库将绑定变量的内容解释为查询的一部分。始终验证不受信任的输入,以确保其符合预期的格式,并尽可能使用集中式数据验证例程。

你能给我建议如何解决这个问题吗?谢谢:)

java sql注入 spring-jdbc veracode

评论

0赞 Andreas 8/31/2020
我假设如果参数不是所有有效的标识符字符,则会引发异常?如果是这样,那么你的代码是安全的,但 Veracode 不知道什么是安全的,所以它不知道你已经防范了 SQL 注入。--- 在 Web 上搜索 Veracode 忽略,以查找用于抑制该特定代码问题的选项。checkEntityName()checkEntityName()
3赞 Evan Gertis 4/28/2021
我很想知道你是否在这方面取得了任何进展。

答:

0赞 SmlCodes 5/15/2023 #1

如果即使使用,它仍然给出异常,请尝试使用以下代码清理本机 SQL 查询字符串。PrepareStatement

private static String sanitizeQuery(String query) {
    return query
        .chars()
        .mapToObj(i -> (char) i)
        .map(String::valueOf)
        .collect(Collectors.joining());
}