2

我正在调用一个 Web 服务并将其传递给动态生成的 SQL 字符串。此字符串包含用户输入。它目前正在使用简单的字符串连接构建,因此容易受到 SQL 注入攻击。我不能使用正常的参数化 SQL 解决方案,因为我没有从我的应用程序执行命令。

我的第一次尝试是构建一个参数化的 SqlCommand 对象。但是,似乎没有任何方法可以提取最终的 SQL 语句。我的第二次尝试是使用sp_executesql,但这似乎与我的原始代码存在相同的问题:将 SQL 命令与用户输入连接在一起。

那么,如何在不编写自己的输入清理逻辑的情况下生成 SQL(即.Replace("'", "''")?是否有可用的内置类或良好的第三方库?

4

1 回答 1

3

据我了解这个问题......如何在不编写我自己的输入清理逻辑的情况下生成 SQL。有几种 sql 注入缓解技术需要考虑使用。其中一些是基于后端的安全性,而另一些则是由数据库引擎强制执行的业务和应用程序开发规则。

后端安全:始终应用“最低权限”规则:为访问 DBMS 的应用程序设置低权限数据库帐户。服务器端卫生:在服务器端。验证用户提供的数据——以及从潜在不安全的来源获得的任何数据客户端输入验证可能很有用

客户端:不要向用户返回 SQL 错误消息,因为它们包含对攻击者有用的信息,例如有关目标表甚至其内容的查询或详细信息。在 Java 中使用异常处理可以很容易地防止这种情况发生。

客户端:使用 Base64 等双向函数将可能包含有问题字符的文本输入字段编码为字母数字版本。

客户端:主动编写代码以防止 SQL 注入。通过两步过程过滤所有输入数据。首先,在用户输入集合(例如,Web 表单)中应用白名单过滤:仅允许与字段相关的字符、字符串格式和数据类型;限制字符串长度。然后,在生成 SQL 查询之前,应在数据访问层应用黑名单过滤或转义:转义 SQL 元字符和关键字/运算符。

客户端或中间层:使用严格的白名单过滤验证动态生成的数据库对象名称(例如表名称)。

客户端避免引用/分隔标识符,因为它们会使所有白名单、黑名单和转义工作变得非常复杂。

开发:强制流程为开发人员提供一个安全的 API,该 API 将负责安全性并避免 SQL 注入。这样做而不是依赖开发人员来实现复杂的防御性编码技术。

API:开发一个 API 或 middel 层,在编译时分析数据库模式,并为一组自定义的 SQL 查询构造类编写代码(然后集成到 IDE 中,并由开发人员直接调用以构建 SQL 查询)。结果是基于通用模板的树状结构,根据表和列定义映射 SQL 查询的可能变化。有 3 种主要类型的类:SQL 语句、表列和 where 条件。这些类具有映射数据库模式中数据类型的强类型方法。攻击面减少。建议的 API 不会执行您在问题中指定的查询,它只会生成 SQL。提议的 API 将在输入值提交时根据其映射检查数据类型。第二,该查询将由特定于 DBMS 的驱动程序使用 JDBC 的 PreparedStatement 接口和绑定变量进行预编译。任一步骤中的任何错误都将阻止查询的执行。

开发人员使用的提议的 API 设计将解决服务器端验证、SQL 错误拦截。直接强制执行强类型,而不需要文本输入编码和两步输入验证,因为动态输入是通过 PreparedStatement 接口通过单独的受保护数据通道(绑定变量)注入的。对象名称不是由用户输入的,而是经过例行验证的。但是,仍应向提议的 API 提供低权限的数据库帐户。

在提议的 API 中,不需要识别数据输入入口点,因为在数据库交互之前应用了保护。完全支持分段查询;由于每个查询修改都由 API 验证,因此可以确保它们的安全性。白过滤和黑名单是不必要的,因为动态输入是使用绑定变量指定的。

在提议的 API 中,列长度(例如,对于 varchar 字段)可以存储在 DB 类中(就像名称和数据类型一样),从而允许解决方案对输入数据执行边界验证,从而提高其保护级别和整体准确性。

类似 API 设计的基于 Java 的原型正在开发中,并且正在进行研究。

于 2012-04-13T17:41:04.353 回答