我实现了一个允许使用MySQL查询来过滤结果的系统。 "问题"我需要检查查询是否包含一些MySQL命令,以避免它们的执行(诸如drop,delete,truncate等命令)。 目前我的代码如下:
$query = "SELECT * FROM thetable";
$notAllowedCommands = array(
'DELETE',
'TRUNCATE',
'DROP',
'USE'
);
$containsNotAllowedCommands = false;
foreach($notAllowedCommands as $notAllowedCommand){
$upperCaseQuery = strtoupper($query);
if(strpos($upperCaseQuery, $notAllowedCommand) !== false){
$containsNotAllowedCommands = true;
break;
}
}
问题是,如果我添加以下查询:
SELECT * FROM USERS
strpos会找到' USE' USERS(表名)中的(命令)。
如果我使用别名或列名(例如,deleted_records),则相同。
有关如何避免这种情况的任何建议吗?
提前致谢
修改 看到建议后,这就是我现在要实施的解决方案:
$containsNotAllowedCommands = false;
// Remove unwanted newlines and tabs and replace them with space.
$singleLineQuery = preg_replace("/[\r\n]+/", " ", $query);
// Convert the entire query to upper case (for comparison) and explode
$explodedQuery = explode(' ', strtoupper($singleLineQuery));
// Check if the intersection of both arrays is greater than zero
if(count(array_intersect($notAllowedCommands, $explodedQuery)) > 0){
$containsNotAllowedCommands = true;
}
我希望将来对其他人有用:D
谢谢你们!
答案 0 :(得分:3)
你可以试试像 -
这样的东西$notAllowedCommands = array(
'DELETE',
'TRUNCATE',
'DROP',
'USE'
);
$query = "delete * FROM thetable";
if(preg_match('[' . implode(' |', $notAllowedCommands ) . ']i', $query) == true) {
echo 'true';
}
else
{
echo 'false';
}
preg_match
将检查字符串中的这些单词。表达式为 - [DELETE |TRUNCATE |DROP |USE]i
,它将检查具有尾随空格的单词,并且不区分大小写。
你也可以试试这个 -
$notAllowedCommands = array(
'DELETE',
'TRUNCATE',
'DROP',
'USE',
'delete',
'drop'
);
$query = "select * FROM users";
$temp= explode(' ', $query);
if(count(array_intersect($notAllowedCommands, $temp)) > 0)
{
echo "true";
}
else
{
echo "false";
}