【发布时间】:2014-05-07 13:13:49
【问题描述】:
我的一个同事写了一些非常糟糕的东西。 我们的老板希望能够从我们网站的后台编写任何 SELECT 查询,然后以 CSV 格式获取结果。
这些查询将由我们的 PRODUCTION MySQL 集群执行。 此后台功能应拒绝任何非 SELECT 查询。
所以他想出了一个非常幼稚的解决方案。 这是PHP代码:
function checkQuery()
{
$sQuery = trim($_POST['query']);
if (empty($sQuery))
return false;
$sCmd = substr($sQuery, 0, 6);
if (strtolower($sCmd) != 'select')
return errorDiv('Only SELECT queries are authorized');
return $sQuery;
}
对于不懂 PHP 的人,这段代码会从 SQL 查询字符串的开头和结尾删除空格,然后获取前 6 个字符,将它们转换为小写字符,如果不匹配 (erf.. . 松散匹配) 'select',查询被拒绝。
对我来说,这看起来很糟糕,很恶心。 我试图说服他至少创建另一个具有有限权限的 MySQL 用户,但他懒得这样做。
但是我无法证明他可以进行某种黑客攻击。
他使用 mysql_query() 来运行查询字符串,这个驱动程序一次拒绝多个查询。 我找不到任何真正的漏洞利用,但我认为至少有 50% 的可能性会发生不好的事情。
也许一些 NUL 字符或一些模糊的 utf-8 字符可以解决问题?
【问题讨论】:
-
我认为“select * from sys.object; drop table XXXX”会造成一些损害
-
@GunnarKnudsen:
mysql_query()最多只能执行一个查询。 -
“我试图说服他至少创建另一个 MySQL 用户,但权限有限,但他懒得这么做。”我会考虑辞职,并在一个更有能力、更专业的环境中工作。在我看来,这是解决这里基本技术问题的唯一方法。
-
其实我知道应该如何干净安全地完成,我要问的是如何破解当前的解决方案,之前部署这个丑陋的东西,所以我可以停止它。
-
@Vesper,MySQL 不支持
SELECT ... INTO TABLE。