最终的清洁/安全功能

时间:2010-11-19 10:09:49

标签: php security xss sql-injection

我有很多来自$_GET$_POST的用户输入...目前我总是写mysql_real_escape_string($_GET['var']) ..

我想知道您是否可以立即创建一个保护,逃避和清除$_GET / $_POST数组的函数,这样您每次都不需要处理它使用用户输入等。

我在考虑一个函数,例如cleanMe($input),在其中,它应该mysql_real_escape_stringhtmlspecialcharsstrip_tagsstripslashes(我认为)这将使它变得干净和安全),然后返回$input

这可能吗?制作适用于所有$_GET$_POST的功能,因此您只需执行此操作:

$_GET  = cleanMe($_GET);
$_POST = cleanMe($_POST);

因此,在以后的代码中,当您使用例如$_GET['blabla']$_POST['haha']时,它们会受到保护,剥离等等吗?

尝试了一下自己:

function cleanMe($input) {
   $input = mysql_real_escape_string($input);
   $input = htmlspecialchars($input, ENT_IGNORE, 'utf-8');
   $input = strip_tags($input);
   $input = stripslashes($input);
   return $input;
}

7 个答案:

答案 0 :(得分:122)

通用卫生功能的概念是一个破碎的概念。

对于各种目的,都有一个正确的卫生方法。在字符串上不加选择地运行它们通常会破坏它 - 为SQL查询转义一段HTML代码会破坏它以便在网页中使用,反之亦然。应使用数据之前应用卫生设施:

  • 在运行数据库查询之前。正确的卫生方法取决于您使用的库;它们列在How can I prevent SQL injection in PHP?

  • htmlspecialchars()用于安全的HTML输出

  • preg_quote()用于正则表达式

  • escapeshellarg() / escapeshellcmd()用于外部命令

  • 等。等

使用“一刀切”的卫生功能就像在植物上使用五种高毒性杀虫剂一样,根据定义,它只含有一种虫子 - 只是为了发现你的植物被第六种侵染,没有任何杀虫剂起作用。

在将数据传递给函数之前,始终使用一种正确的方法,理想情况下是直接的。除非您需要,否则从不混合方法。

答案 1 :(得分:7)

简单地通过所有这些函数传递输入是没有意义的。所有这些功能都有不同的含义。通过调用更多的escape函数,数据不会变得“干净”。

如果要在MySQL中存储用户输入,则只需使用mysql_real_escape_string。然后完全转义以安全地存储在数据库中。

修改

另请注意使用其他功能时出现的问题。如果客户端向服务器发送了一个用户名,并且用户名包含&符号(&),那么在将其存储到数据库中之前,您不想调用htmlentities,因为那时用户名是数据库将包含&

答案 2 :(得分:6)

您正在寻找filter_input_array()。 但是,我建议仅将其用于业务风格的验证/清理,而不是SQL输入过滤。

为防止SQL注入,请使用mysqliPDO的参数化查询。

答案 3 :(得分:3)

问题是,一次使用时干净或安全的东西不适用于另一种:清除部分路径,部分mysql查询,html输出(作为html,或者在javascript或输入中)值),对于xml可能需要不同的东西相矛盾。

但是,可以做一些全球性的事情。 尝试使用filter_input来获取用户的输入。并使用prepared statements进行SQL查询。

虽然您可以创建一些管理输入的类,而不是全部功能。这样的事情:

class inputManager{
  static function toHTML($field){
    $data = filter_input(INPUT_GET, $field, FILTER_SANITIZE_SPECIAL_CHARS);
    return $data;
  }
  static function toSQL($field, $dbType = 'mysql'){
    $data = filter_input(INPUT_GET, $field);
    if($dbType == 'mysql'){
      return mysql_real_escape_string($data);
    }
  }
}

有了这样的东西,如果你在代码中看到任何$ _POST,$ GET,$ _REQUEST或$ _COOKIE,你知道你必须改变它。如果有一天你必须改变过滤输入的方式,只需改变你所做的课程。

答案 4 :(得分:1)

如果您使用的是apache并且可以完全访问服务器,我建议安装“mod_security”吗?!
它确实解决了我的大部分问题。但是,不要只依赖一两个解决方案,总是编写安全代码;)
更新的 找到这个PHP IDS(http://php-ids.org/);看起来很不错:))

答案 5 :(得分:0)

<?php
function sanitizeString($var)
{
    $var = stripslashes($var);
    $var = strip_tags($var);
    $var = htmlentities($var);
    return $var;
}

function sanitizeMySQL($connection, $var)
{
    $var = $connection->real_escape_string($var);
    $var = sanitizeString($var);
    return $var;
}
?>

答案 6 :(得分:-1)

我使用了传递数组或获取,发布

function cleanme(&$array)
{ 
 if (isset($array))
 {
     foreach ($array as $key => $value)
     {
          if (is_array($array[$key]))
          {
           secure_array($array[$key]);
          }
          else 
          {
            $array[$key] = strip_tags(mysql_real_escape_string(trim($array[$key])));
          }
     }
 }
}

用法:

cleanme($_GET);   
cleanme($_POST);