正则表达式冗余或额外的安全性


Regex redundancy or extra security?

假设我有一个使用正则表达式清理字符串的函数:

function RegExCleaner($var)
{
    return preg_replace('Regular expression', '', $var)
}

函数的外观和工作方式并不那么重要。只是一个简单的例子。

如果我使用这个函数来清理用户输入或一些值一次,然后与值'服务器端'工作,它是否足以清理它一次或我可以做多层?那么如果我在一系列函数中使用变量,我是否在每个函数中都清除它?这是否真的提高了安全性,或者我只是增加了不必要的工作负载?

基本上有两种方式处理用户输入:

  1. Sanitizing:这将从输入中删除不需要的东西。不需要的东西可能是各种标签,无效格式的字符,某些单词或字母等。这几乎总是你应该做的事情。唯一的例外是如果输入是一个简单的值,如整数或布尔值,可以通过验证直接处理。

  2. 验证:这确保输入确实是您所期望的。它是一个数字,布尔值,文本块等?这与其说是关于安全,不如说是关于获取正确类型的数据以使程序能够运行。

对于这两个点,有一个名为Filter的PHP扩展。它是用这些东西制作的。

对输入进行消毒,你可以这样做:

$name     = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
$age      = filter_input(INPUT_POST, 'age', FILTER_SANITIZE_NUMBER_INT);
$email    = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$password = filter_input(INPUT_POST, 'password', FILTER_UNSAFE_RAW);

验证:

if (preg_match('/['w'd]{4,20}/', $name) === 0) {
    die('Invalid name!');
}
if ( ! ctype_digit($age) || ($age < 13)) {
    die('Invalid age or too young!');
}
if ( ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
    die('Invalid email address!');
}
if (strlen($password) < 10) {
    die('Password is too short!');
}

要记住的一件非常重要的事情是,没有神奇的药丸。用户输入的信息不能在输入时直接用漂白剂清洗,然后就说安全了。您需要知道用户输入应该是什么,然后相应地处理它。如果它不是你所知道的那样,那么立即踩刹车,把它扔给用户。

最好有一个地方发生这种情况。在进入系统的过程中清理所有东西,然后你就没有什么可担心的了。如果你在很多地方消毒,跟踪你在哪里消毒也会让人感到困惑。在每个级别上进行消毒不会损害您的逻辑,但由于这个原因,它可能会使维护变得更加困难。

我推荐一个函数库来清理输入,可能包装在一个类中,例如作为静态方法,并通过这些函数之一传递所有内容。