Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySQL-检查查询的前6个字符以确保它是SELECT是否安全?_Php_Mysql_Sql - Fatal编程技术网

Php MySQL-检查查询的前6个字符以确保它是SELECT是否安全?

Php MySQL-检查查询的前6个字符以确保它是SELECT是否安全?,php,mysql,sql,Php,Mysql,Sql,我的一个同事写了一些非常糟糕的东西。 我们的老板希望能够从我们网站的后台编写任何选择查询,然后以CSV格式获得结果 这些查询将由我们的生产MySQL集群执行。 此后台功能应拒绝任何非SELECT查询 因此,他提出了一个非常幼稚的解决方案。 这是PHP代码: function checkQuery() { $sQuery = trim($_POST['query']); if (empty($sQuery)) return false

我的一个同事写了一些非常糟糕的东西。 我们的老板希望能够从我们网站的后台编写任何选择查询,然后以CSV格式获得结果

这些查询将由我们的生产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字符可以做到这一点?

使用此功能的正确方法(如果你不能说服他这是个坏主意)是以有限的MySQL用户身份运行查询。仅授予该用户
SELECT
权限。如果需要,您还可以限制表集。

我看不到任何方法可以绕过您同事的
检查查询
例程。如果您没有在PHP中使用
mysql.*
函数,这将是微不足道的,但由于它们只允许执行一条语句,因此它们至少不会受到诸如攻击样式之类的经典攻击。事实上,这也是为什么
mysql\u*
mysqli\u*
中的标准查询函数都不允许使用多个语句的关键原因之一(这在中有描述)

我已经研究了其他路线,我非常满意您同事的代码确实有效。(有一种生成误报的方法,例如,即使在有效的SELECT查询中也会触发检测,但这对您没有多大用处。)并且只要您没有将更改数据作为副作用的函数,除了使用以
SELECT…
开头的语句执行
SELECT
,就不可能执行任何操作

可以使用将新文件写入服务器。这仅限于新文件,因此您不能关闭/etc/passwd或其他任何文件,但存在危险

我能看到的最危险的情况是,如果您的MySQL服务器与PHP服务器是同一台机器,您的MySQL用户可以写入您的PHP目录,并且您使用的用户具有文件权限。在这种情况下,一个精心制作的
SELECT。。。沿以下线路输入输出文件

SELECT '<?php echo \'DANGER WILL ROBINSON!\';' INTO OUTFILE '/Users/matt/Sites/dangerous.php'

SELECT'我假设“SELECT*from sys.object;drop table XXXX”可以执行一些操作damage@GunnarKnudsen<代码> mySqLyQuices()最多只能执行一个查询。“我试图说服他创建至少另一个MySQL用户,权限有限,但他太懒了,不能这么做。”我会考虑辞职。以及在一个更有能力、更专业的环境中工作。在我看来,这是解决基本技术问题的唯一方法。实际上,我知道应该如何干净安全地完成,我要问的是如何在部署这个丑陋的东西之前破解当前的解决方案,这样我才能阻止它。@Vesper,MySQL不支持
SELECT。。。也可以限制存储过程/函数的运行?@frlan MySQL
选择。。。进入表格
。感谢您的努力,我接受答案。我们的系统管理员知道这一点,并且没有授予任何文件权限,而且PHP和MySQL在不同的服务器上运行。顺便说一句,我会再次尝试说服他以正确的方式做这件事,但我很确定没有什么会改变。。。我怀疑他暗自为自己的解决方案感到骄傲