我正在审查一个基于Linux的perl Web应用程序,它包含一个无处不在的登录处理程序
我的$ sth = $ DB-> prepare(“从密码中选择密码,其中userid ='$ userid'”)或死; $ sth->执行或死亡; ...
其中$ userid是从(不安全,未经过滤的)Web用户输入初始化的 .
众所周知,DBI文档建议应该更改此代码以使用占位符“?”取代'$ userid'以获得安全性 .
This code was isolated on an off network box, as-is, for the purpose of a security review. 在互联网服务器上这样的代码最终会被破解,因为现在有机器人正在扫描此漏洞 . 访问控制对于保护任何重要内容也无效,因为已知注入可以删除数据库,插入错误数据或新用户,或绕过访问控制以允许进入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 回答
默认情况下,MySQL客户端库似乎限制为每个调用一个语句(我在PHP中遇到过它) .
但是,这不应该是使用MySQL而不是PostgreSQL的理由,因为您仍然可以使用子查询进行注入 .
防止注入攻击不是数据库的责任,它是开发人员的责任 . 如果开发人员编写通过连接从用户输入派生的字符串来创建查询的代码,则生成的查询将容易受到注入攻击,并且所有用于清理等的代码都是恕我直言,浪费时间 . 如果编写代码以使用参数化查询,并且用户输入被降级为用作参数值,则生成的查询将在注入攻击中相当安全 . (我有兴趣听听如何通过参数值进行注射攻击) .
分享和享受 .
不,实际上,MySQL几乎没有特别的安全性,在这种情况下,好像准备语句根本没有在服务器上完成 .
据推测,它们是在PostgreSQL的服务器上准备的 .
就安全性而言,你只是做错了:使用
?
正好利用Postgres可以准备多个语句:而且这并不依赖于其他来源作为服务器的权威 . 现在DBD :: MySQL可能在一个mysql库中使用C函数,该库早于具有服务器端准备的MySQL(4.1.3是我的猜测) .对于SQL注入,可能很难(如果不是不可能的话)使用通用的消毒剂 .
添加[As注释,使用DBI正确并在DB _1453649的帮助下,重要的是要记住,清理用户输入还涉及独立于所使用的DB的应用程序逻辑 . 例如,使用其他用户的凭据可能会提供有效且安全的声明,但会产生意想不到的后果 . 无论如何,这比问题更进一步 . ]
删除[你最好自己消毒输入,而不是对客户端抵抗这些类型的攻击有任何虚假的安全感 . 并不是说你不应该使用它们,只是不要认为它们提供的不仅仅是对攻击的最小帮助 .