2

我刚刚(偶然)在我正在从事的项目中发现了另一个愚蠢的根本没有清理的 sql 注入缺陷......我已经厌倦了。
您对如何消除此类不良 sql 语句并在可行的情况下强制执行准备好的语句有任何建议吗?现在我更喜欢这样的解决方案

REVOKE DarnInlineDataStatements ON * TO xyz
但是由于这似乎不太可能,是否有例如静态代码分析工具来查找这些东西(达到一定的可靠性)?或者还有什么你会推荐的?
编辑:软技能方法“请不要使用它们,(通常)有更好的方法”在过去似乎效果不佳。因此,我真的更喜欢首先阻止此类查询的东西。不是故意破坏现有代码,而是为了未来的项目,一些“没有这样的查询”解决方案;-)

4

5 回答 5

3

如果将 sql 移动到存储过程,则可以禁用应用程序用户的 SELECT、CREATE、ALTER、UPDATE、DELETE、DROP 等权限,只保留 EXEC 访问权限。这假设 SQL Server,但我确信 Oracle/MySQL 等允许类似的设置。

另请注意,这不能保证准备好的语句:您仍然可以以不安全的方式调用存储过程。但是如果你没有使用很多存储过程,它会找到任何编码不正确的地方,如果你遗漏了任何东西,那么sql注入攻击就很难成功。

于 2009-02-28T01:37:12.987 回答
2

你可以在你的代码库中搜索常见的 T-SQL 结构,例如 SELECT、INSERT、UPDATE、DELETE 等。

如果您使用的是 Visual Studio 2008 Team System,则有一个内置的代码分析规则可以检查一些 SQL 问题。否则,有免费的FxCop

于 2009-02-28T01:20:56.380 回答
1

如果您已经在使用静态代码分析工具,则可以将其配置为查找某些方法的使用情况,例如在 Java 世界中Connection.createStatement而不是Connection.prepareStatement.

我认为更好的方法是让团队了解创建具有串联的动态 SQL 的不良影响。您必须将其添加到您的编码标准文档中!

于 2009-02-28T01:22:22.007 回答
0

希望在您的软件中轻松找到所有非参数化查询。大多数数据库访问层(如 PHP 的 PDO 或 Perl 的 DBI)在准备查询时的调用与仅执行 SQL 时的调用不同。弄清楚这些调用是什么并搜索代码将为您提供一个良好的开端。如果您使用 Linux,grep 是您的朋友。

从那里修复它们将很容易(我希望)。我不知道项目的大小,但您可能应该将查询放在一个共同的地方,或者基于 Active Record / DataMapper / Table Row Gateway 等共同模式开发一些层。

我认为没有自动执行它的好方法。也许你只需要与你的同事心连心。内联 SQL 不好。故事结局。如果你是领导者,我认为授权将是有序的。

于 2009-02-28T01:30:30.133 回答
0

不要让您的应用程序将代码直接发送到数据库服务器,而是通过中间层发送。它可以轻松解析要发送到数据库的任何内容并对其施加一些约束。例如,强制所有 SQL 代码由一个且不超过一个语句组成,如果有多个语句,则要么拒绝它,要么只执行第一个语句。

基本的 SQL 注入攻击涉及如下代码:

DECLARE @SQL VARCHAR(4000), @Table VARCHAR(50) 
SET @Table='Employees' -- Imagine this actually comes as a parameter from app
SET @SQL='SELECT * FROM '+@Table
EXEC(@SQL)

攻击者可以传递字符串“systables';UPDATE BankAccount SET Money=Money+10000 WHERE AccountCode=12345;DROP TABLE AuditTrails;” 到数据库 - 它会产生灾难性的影响。

通过让中间层对字符串进行最少的解析,您可以免受这种最简单的 SQL 注入攻击。对于其他人,您可以将它们添加到中间层(它还可以处理结果缓存、带宽限制等)

如果您需要从您的应用程序传递多个 SQL 语句,我会说您做错了,应该将该逻辑封装在存储过程中,或者至少在中间层本身。

于 2009-02-28T05:40:47.083 回答