检查GET参数的功能

时间:2015-07-22 18:02:10

标签: php

我有一个对我的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);是否足以从任何恶意代码中清除我的变量?

1 个答案:

答案 0 :(得分:1)

严格回答你的问题,问题在于preg_replace。在原始版本中,除了明确列出的字符之外的任何字符都替换为“”,从输入中有效地删除它们。例如,“2 ^ 8”将变为“28”,因为不允许^

要接受"invisible control characters and unused code points"以外的任何字符,请将此函数中的preg_replace替换为:

return preg_replace('@(\p{C})@ui', "", $content);

Working implementation

修改

响应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';
}