MySQL比PostgreSQL(在Perl / DBI下)更能抵抗SQL注入攻击吗?

时间:2010-02-08 13:16:06

标签: mysql perl postgresql sql-injection dbi

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

我的$ sth = $ DB->准备(“从密码中选择密码,其中userid ='$ userid'”)或死亡; $ sth->执行或死亡; ...

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

众所周知,DBI文档建议应该更改此代码以使用占位符“?”代替'$ userid'以获得安全性。

为了进行安全审查,此代码已在离网网络盒中被隔离。在互联网服务器上这样的代码最终将被破解,因为现在有机器人扫描对于此漏洞。访问控制对于保护任何重要内容也无效,因为已知注入可以删除数据库,插入错误数据或新用户,或绕过访问控制以允许进入Web应用程序。

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

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

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

据我所知,MySQL一般不具备SQL注入抗性。

这不仅仅是关于消除SQL注入的技术的问题;为此可能会看到How can I avoid SQL injection attacks?

问题是:在PERL DBI下,MySQL是否比PostgreSQL对SQL注入攻击更具抵抗力?为什么会出现这种情况呢?

4 个答案:

答案 0 :(得分:11)

防止注入攻击不是数据库的责任,它是开发人员的责任。如果开发人员编写通过连接从用户输入派生的字符串来创建查询的代码,则生成的查询将容易受到注入攻击,并且所有用于清理等的代码都是恕我直言,浪费时间。如果编写代码以使用参数化查询,并且用户输入被降级为用作参数值,则生成的查询将在注入攻击中相当安全。 (我有兴趣听听如何通过参数值进行注射攻击)。

分享并享受。

答案 1 :(得分:8)

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

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

答案 2 :(得分:3)

不,实际上,MySQL几乎没有特别的安全性,在这种情况下,好像准备语句根本没有在服务器上完成。

  

准备好的声明支持(服务器   方准备)自3.0002_1起,服务器   旁边的准备声明是由   默认(如果您的服务器是> = 4.1.3)。   截至3.0009,它们默认是关闭的   再次由于准备的问题   语句API(所有其他mysql   连接器以这种方式设置,直到C   API问题已解决)。该   要求使用准备好的陈述   仍然是你有一个服务器'> = 4.1.3'

     

使用服务器端准备   声明,您需要做的就是设置   变量mysql_server_prepare in   连接:

     

$ dbh = DBI-> connect(   “DBI:MySQL的:数据库=测试;主机=本地主机; mysql_server_prepare = 1”,   “”,“”,{RaiseError => 1,AutoCommit   => 1});

     
      
  • 注意:此参数的分隔符为“;”
  •   
     

使用有很多好处   主要是服务器端准备语句   如果您正在执行许多插入   因为那个单一的事实   声明准备接受   多个插入值。

     

确保'make test'步骤   测试服务器准备工作,   你只需要导出env   变量MYSQL_SERVER_PREPARE:

     

导出MYSQL_SERVER_PREPARE = 1

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

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

答案 3 :(得分:0)

对于SQL注入,可能很难(如果不是不可能的话)使用通用的消毒剂。

添加[如已注释,正确使用DBI并在DB的客户端库的帮助下,可以在准备SQL语句时最小化注入。但是,重要的是要记住,清理用户输入还涉及独立于所使用的DB的应用程序逻辑。例如,使用其他用户的凭据可能会提供有效的安全语句,但会产生意想不到的后果。无论如何,这比问题要多得多。]

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