为什么 Veracode 会报告 CWE-89?

问题描述 投票:0回答:1

我有这个用 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);
        }
    }

对于缓解缺陷,我正在使用函数

checkEntityName
应该使它们静音(在 Veracode 扫描期间使它们误报)

    @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 仍然报告这个问题:

漏洞编号:1433

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

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

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

java sql sql-injection spring-jdbc veracode
1个回答
0
投票

如果即使使用

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

private static String sanitizeQuery(String query) {
    return query
        .chars()
        .mapToObj(i -> (char) i)
        .map(String::valueOf)
        .collect(Collectors.joining());
}
© www.soinside.com 2019 - 2024. All rights reserved.