4

我正在审查一个基于 Linux 的 perl Web 应用程序,它包含一个登录处理程序

my $sth = $DB->prepare("SELECT password from passwords where userid='$userid'") or die; $sth->执行或死亡;...

其中 $userid 是从(不安全、未过滤的)Web 用户输入初始化的。

众所周知,DBI 文档建议将此代码更改为使用占位符“?”。代替 '$userid' 以确保安全。

出于安全审查的目的,此代码按原样隔离在一个离线盒子上。 互联网服务器上的此类代码最终将被破解,因为现在有机器人扫描此漏洞。访问控制对于保护任何重要的东西也无效,因为已知的注入可以删除数据库、插入坏数据或新用户,或者绕过访问控制以允许进入 Web 应用程序。

由于可以将应用程序配置为使用 PostgreSQL 或 MySQL,并且提出了关于比较漏洞的问题,我尝试了这两个数据库并使用一些 SQL 注入尝试测试了每个配置。

在 PostgreSQL 下输入 '; 在这里做坏事;和这里; 会按预期使登录 cgi 崩溃并执行坏的东西。

出乎意料的是,MySQL 抵抗了这种攻击。这让我想知道 DBD::MySQL 或其他地方是否有某种设置限制每次调用准备 1 个语句,或者 MySQL 是否以其他方式抵抗。

据我了解,MySQL 通常不支持 SQL 注入。

这不仅仅是一个关于消除 SQL 注入技术的问题。为此,请参阅如何避免 SQL 注入攻击?.

问题是:在 PERL DBI 下,MySQL 是否比 PostgreSQL 更能抵抗 SQL 注入攻击?为什么会这样?

4

4 回答 4

12

防范注入攻击不是数据库的责任,而是开发者的责任。如果开发人员编写的代码通过连接从用户输入派生的字符串来创建查询,那么生成的查询将容易受到注入攻击,并且所有花费在清理等上的代码,恕我直言,是浪费时间。如果编写代码以使用参数化查询,并且将用户输入降级为用作参数值,则生成的查询将相当安全地免受注入攻击。(而且我很想知道如何通过参数值进行注入攻击)。

分享和享受。

于 2010-02-08T17:43:17.997 回答
8

默认情况下,MySQL 客户端库似乎限制每次调用一个语句(我在 PHP 中遇到过)。

但这不应该成为使用 MySQL 而不是 PostgreSQL 的理由,因为您仍然可以使用子查询进行注入。

于 2010-02-08T13:29:01.857 回答
3

不,事实上,MySQL 几乎绝对不安全,在这种情况下,似乎准备语句根本没有在服务器上完成。

准备语句支持(服务器端准备) 从 3.0002_1 开始,服务器端准备语句默认启用(如果您的服务器 >= 4.1.3)。从 3.0009 开始,由于预处理语句 API 的问题,它们再次默认关闭(所有其他 mysql 连接器都以这种方式设置,直到 C API 问题得到解决)。使用准备好的语句的要求仍然是你有一个服务器'> = 4.1.3'

要使用服务器端准备好的语句,您需要做的就是在连接中设置变量 mysql_server_prepare:

$dbh = DBI->connect("DBI:mysql:database=test;host=localhost;mysql_server_prepare=1", "", "", { RaiseError => 1, AutoCommit => 1 } );

  • 注意:此参数的分隔符是 ';'

使用服务器端准备语句有很多好处,主要是在执行许多插入时,因为单个语句准备接受多个插入值。

为确保“make test”步骤测试服务器准备工作是否有效,您只需导出环境变量 MYSQL_SERVER_PREPARE:

导出 MYSQL_SERVER_PREPARE=1

据推测,它们是在 PostgreSQL 的服务器上准备好的。

就安全性而言,您只是做错了:?按照您所说的使用。否则,您只是在利用 Postgres 可以准备多个语句:这不是负面的。我相信 MySQL 也可以做到这一点,这里唯一的区别是 DBD::MySQL 声称 C API 问题排除了服务器端准备的使用,因此它们依赖于其他一些来源作为服务器的权威。现在 DBD::MySQL 可能在 MySQL 库中使用 C 函数,该库早于 MySQL 具有服务器端准备(我的猜测是 4.1.3 之前)。

于 2010-02-08T18:25:27.810 回答
0

拥有针对 SQL 注入的通用消毒剂可能很困难,如果不是不可能的话。

添加了 [如评论所述,正确使用 DBI 并在 DB 客户端库的帮助下,在准备 SQL 语句方面肯定可以最大限度地减少注入。但是,重要的是要记住,清理用户输入还涉及独立于所用数据库的应用程序逻辑。例如,使用另一个用户的凭据可能会提供有效且安全的声明,但会产生意想不到的后果。无论如何,这比所提出的问题更进一步。]

删除 [你最好自己清理输入,而不是对客户端对这些类型的攻击的抵抗力有任何虚假的安全感。并不是说您不应该使用它们,只是不要认为它们提供的帮助只是针对攻击的最低限度。]

于 2010-02-08T13:47:42.097 回答