java 为什么Veracode报告CWE-89?

xdyibdwo  于 2023-05-15  发布在  Java
关注(0)|答案(1)|浏览(111)

我用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仍然报告了这个问题:
缺陷ID:1433
说明:此数据库查询包含SQL注入缺陷。对java.sql.Statement.executeQuery()的调用使用从不受信任的输入派生的变量构造一个动态SQL查询。攻击者可以利用此缺陷对数据库执行任意SQL查询。executeQuery()的第一个参数包含来自变量format()的污染数据。受污染的数据源自对java.sql.Statement.executeQuery的早期调用。
补救措施:避免动态构造SQL查询。相反,应使用参数化的预准备语句来防止数据库将绑定变量的内容解释为查询的一部分。始终验证不受信任的输入,以确保它符合预期的格式,尽可能使用集中式数据验证例程。
你能给予我一些建议如何解决这个问题吗?Thank you:)

fzsnzjdm

fzsnzjdm1#

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

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

相关问题