我正在开发一个已经通过SQL注入攻击的网站(乍一看只有数据库条目被跨网站脚本损坏)我查看代码后发现的潜在漏洞是有很多mysql_query调用其输入完全没有转义。
好老:
$query = "SELECT * FROM mytable where name LIKE '%".$_GET['name']."%'"; /*HACK HERE*/
mysql_query($query, $connection);
然而,我无法找到我们如何从注入漏洞中做一些很酷的事情(通过酷我的意思是INSERT或UPDATE)。我试图建立一个像这样的声明:
SELECT * FROM mytable where name LIKE '%' AND WHERE id IN (INSERT INTO secondtable (id,description) VALUES (15, 'Fifteenth description');--%'
没有成功。我猜INSERT在这里无关。
我现在正在逃避代码中所有用户的输入,但我并没有真正了解黑客如何渗透到这个网站,那么我并不是100%确定我的修复程序能够完成这项工作。有什么好的建议吗?
由于
答案 0 :(得分:3)
根据您使用的mysql版本以及连接的设置,mysql_query可能允许more than one statement。
您应该查看如何创建连接,以及mysql_set_server_option的任何用法。
答案 1 :(得分:2)
由于mysql_query
不支持多个查询,因此任何像'; DROP TABLE mytable; --
这样的注入都不会成功。
但是,攻击者可以与其他select语句结合使用,以选择密码信息等其他信息。
答案 2 :(得分:1)
可能的情况1
弱密码/散列将让攻击者选择管理员的密码
更改所有管理员密码是明智的。
答案 3 :(得分:1)
有趣的是,您的问题尚未收到很多(正确的)答案!
您已经发现,像mysql_query
,mysqli::query
等常用的PHP MySQL API仅在第一个SQL语句通过多个(用分号分隔)的情况下才执行第一条SQL语句,攻击者使用{ {3}}。
后卫提示:从您的代码中清除the most common class of SQL injections和朋友;微小的性能提升是不值得冒险的。
PHP人士的这一巧妙举动是否会完全关闭某些"SELECT yadda yadda" . $_GET["untrusted"]
代码上的所有攻击渠道?不完全的。如mysqli::multi_query
所述,即使是纯knittl SELECT
也可以通过UNION ALL SELECT
从附近任何有趣的表中使用来提升特权,包括但不限于密码表。 DQL那里提供了足够的提示和技巧,基本上可以以此方式提取整个数据库。
后卫提示: cheat sheets,具有众所周知的技巧:
- 输入验证
关联数组中的- 白名单间接访问
- 准备好的语句( if ,您可以确保它们有效且apply defense-in-depth!)
- 一个not just string escaping in disguise
- 无法令人满意地清除不受信任的输入(例如,可能合法包含SQL敏感标点的博客帖子)时的保护性编码(例如Base64)
- 或ORM,字符串转义
接下来,您可能会发现并非所有的DQL都是无副作用的,尤其是当它以as a last resort only结尾时。
后卫提示::始终在您的MySQL / MariaDB服务器中配置
INTO DUMPFILE somethingsomething
。
最后但并非最不重要的一点是,即使是有能力注入任意SQL的攻击者也受授予Web应用程序整体权限的限制。
后卫提示:通过应用
secure_file_priv
保护您的应用。
- 只有
GRANT
Web应用程序的MySQL用户具有所需的权限。 设计应用程序以使其完全不需要DDL并不是一个坏主意。如果您必须从Web UI中提供“备份/还原数据库”功能或类似功能,请单独使用MySQL用户。- 自动备份,即使它们没用-POLA。
答案 4 :(得分:0)
现在,从任何php开始已经有一段时间了,但一般来说大多数数据访问库都有某种参数化的sql来降低风险。一个快速的谷歌想出了这个为PHP: http://php.net/manual/en/pdo.prepared-statements.php
另一张海报已经描述了如何进行SQL注入,所以我不会深入研究。
答案 5 :(得分:0)
我很确定黑客能够轻松修改查询。即使mysql_query()不支持多个查询,也有办法解决这个问题。你可以使用添加到最后的mysql IF语句,当然这将执行一个全新的查询。
答案 6 :(得分:-3)
$query = "SELECT * FROM mytable where name LIKE '%".$_GET['name']."%'";
$_GET['name']="'; DROP TABLE mytable; -- ";
所以
$query = "SELECT * FROM mytable where name LIKE '%'; DROP TABLE mytable; -- %'";