终极清洁/安全功能

The ultimate clean/secure function

提问人:Karem 提问时间:11/19/2010 最后编辑:Scott ArciszewskiKarem 更新时间:9/28/2022 访问量:66115

问:

我有很多用户输入和...目前我总是写..$_GET$_POSTmysql_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;
}
PHP 安全 XSS SQL注入

评论

54赞 jensgram 11/19/2010
stripslashes() 之后......我的眼睛!mysql_real_escape_string()
0赞 MatTheCat 11/19/2010
我认为数据安全取决于他们做什么以及他们来自哪里。您不一定需要所有的治疗。
13赞 Matthew Flaschen 11/19/2010
使用一次性主清理功能不是正确的解决方案。这就是魔术报价失败的原因。如果需要,可以转义(或使用更好的解决方案,例如准备好的语句)。否则,你会发现你在错误的时间逃跑,而且往往不止一次。所有这些功能都有非常不同的目的,并且有几个(例如 和 ) 本质上是逆向的。参见 [使用 PHP 清理用户输入的最佳方法是什么?(stackoverflow.com/questions/129677) 了解更多信息。mysql_real_escape_stringstripslashes
4赞 rook 11/24/2010
哦,哇,cleanMe() 不会停止所有 xss,也不会做任何事情来停止 sqli,因为 .这是代码是痛苦的。stripslashes()
0赞 T.Todua 9/25/2014
可能的重复 什么是最好的 PHP 输入清理功能?

答:

130赞 Pekka 11/19/2010 #1

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

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

  • 在运行数据库查询之前。正确的卫生方法取决于您使用的图书馆;它们列在如何防止 PHP 中的 SQL 注入?

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

  • preg_quote()用于正则表达式

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

  • 等等等等。

使用“一刀切”的卫生功能就像在植物上使用五种剧毒杀虫剂,根据定义,这些植物只能含有一种虫子 - 却发现你的植物被第六种杀虫剂侵染,而杀虫剂对这种杀虫剂不起作用。

始终使用正确的方法,最好在将数据传递给函数之前直接使用。除非需要,否则切勿混合使用方法。

评论

53赞 Mchl 11/19/2010
我们经历了magic_quotes的“自动化卫生”。再也不会了。
4赞 jensgram 11/19/2010
@Mchl +1 这可能是PHP解决方案中不安全的首要原因。它基本上鼓励了程序员的无知:)
4赞 Matthew Flaschen 11/19/2010
我想补充一点,非常值得考虑使用预处理语句(PDO或mysqli)来代替数据库查询。
2赞 rook 11/24/2010
+1 你一针见血,漏洞完全取决于数据的使用方式。
13赞 Pekka 12/15/2010
@Toby,如果你认为对一个有效(顺便说一句,被接受的)答案投反对票是合适的,因为你不喜欢它的用词,那么这当然是你的特权。但我个人认为这是愚蠢的。
7赞 Tomas 11/19/2010 #2

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

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

编辑

还要注意使用其他功能时出现的问题。例如,如果客户端向服务器发送用户名,并且用户名包含与号(),则不;不希望在将其存储在数据库中之前调用,因为这样数据库中的用户名将包含 。&htmlentities&

0赞 Filipe YaBa Polido 11/19/2010 #3

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

评论

0赞 BoltClock 11/19/2010
mod_security与输入转义、SQL 注入等有什么关系?
0赞 István Ujj-Mészáros 11/19/2010
@BoltClock 请参阅本文中的“常用配置规则”部分,或查看赛门铁克提供的其他配置规则:使用 Apache 和 mod_security 的网络安全设备
0赞 Filipe YaBa Polido 11/19/2010
@BoltClock:这就像一个保镖,即使你搞砸了,他也会在那里帮助你;)
6赞 Alan Pearce 11/19/2010 #4

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

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

3赞 Arkh 11/19/2010 #5

问题是,对于一种用途来说,干净或安全的东西不会用于另一种用途:清理路径的一部分,mysql查询的一部分,html输出(作为html,或在javascript中或输入的值中),对于xml可能需要不同的东西,这与此相矛盾。

但是,一些全球性的事情是可以做到的。 尝试使用 filter_input 来获取用户的输入。并对 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 美元,你就知道你必须改变它。如果有一天你必须改变你过滤输入的方式,只需改变你创建的类。