我有一个对我的GET参数进行安全检查的函数(我不是作者):
function GET($name = NULL, $value = false)
{
$content = (!empty($_GET[$name]) ? trim($_GET[$name]) : (!empty($value) && !is_array($value) ? trim($value) : false));
if (is_numeric($content))
return preg_replace("@([^0-9])@Ui", "", $content);
else if (is_bool($content))
return ($content ? true : false);
else if (is_float($content))
return preg_replace('@([^0-9\,\.\+\-])@Ui', "", $content);
else if (is_string($content)) {
if (filter_var($content, FILTER_VALIDATE_URL))
return $content;
else if (filter_var($content, FILTER_VALIDATE_EMAIL))
return $content;
else if (filter_var($content, FILTER_VALIDATE_IP))
return $content;
else if (filter_var($content, FILTER_VALIDATE_FLOAT))
return $content;
else
return preg_replace('@([^a-zA-Z0-9\+\-\_\*\@\$\!\;\.\?\#\:\=\%\/\ ]+)@Ui', "", $content);
} else false;
}
因此,每当我获取GET参数值时,我都会调用此函数。但是,如果我的GET参数是包含åäö
等特殊字符的字符串,则会被替换。例如,此字符串Detta är en annons
将具有以下输出:Detta r en annons
。
因为我确定它是一个字符串变量,所以可能是filter_var
函数剥离了我的特殊字符。我应该如何重写上面的脚本以保留我的字符串中的特殊字符?
修改
好的,所以上面的脚本是捶打。我一直在寻找其他选择。如果我的目的是将GET参数值插入数据库,那么filter_input(INPUT_GET,"link",FILTER_SANITIZE_STRING);
是否足以从任何恶意代码中清除我的变量?
答案 0 :(得分:1)
严格回答你的问题,问题在于preg_replace
。在原始版本中,除了明确列出的字符之外的任何字符都替换为“”,从输入中有效地删除它们。例如,“2 ^ 8”将变为“28”,因为不允许^
。
要接受"invisible control characters and unused code points"以外的任何字符,请将此函数中的preg_replace
替换为:
return preg_replace('@(\p{C})@ui', "", $content);
修改强>
响应OP编辑,filter_input
是删除潜在危险输入的好方法,而可能可能是特定用例中的所需内容。但是,请理解没有灵丹妙药解决方案。看看this related SO Q&A。
无论如何,您通常要做的是检查用户输入是否符合您的存储要求(类型,长度等),然后使用预准备语句将其插入数据库,然后使用输出转义来防止XSS攻击。伪代码是这样的:
$foo = isset($_GET['foo') ?? false;
if (is_string($foo) && 0 < strlen($foo) && strlen($foo) < 255) {
$sth = $dbh->prepare('INSERT INTO `table` VALUES (?)');
$sth->execute(array($foo));
echo htmlentities($foo);
} else {
echo 'Error: foo is not valid';
}