我有一个“go”脚本可以获取所请求的任何其他脚本,这是我写的用于清理用户输入的内容:
foreach ($_REQUEST as $key => $value){
if (get_magic_quotes_gpc())
$_REQUEST[$key] = mysql_real_escape_string(stripslashes($value));
else
$_REQUEST[$key] = mysql_real_escape_string($value);
}
我还没有看到其他人使用这种方法。有什么理由不去吗?
编辑 - 修改为适用于数组:
function mysql_escape($thing) {
if (is_array($thing)) {
$escaped = array();
foreach ($thing as $key => $value) {
$escaped[$key] = mysql_escape($value);
}
return $escaped;
}
// else
if (get_magic_quotes_gpc()) $thing = stripslashes($thing);
return mysql_real_escape_string($thing);
}
foreach ($_REQUEST as $key => $value){
$_REQUEST[$key] = mysql_escape($value);
}
答案 0 :(得分:9)
我发现在使用数据时逃避数据要好得多,而不是在路上。您可能希望在JSON,XML,Shell,MySQL,Curl或HTML中使用这些数据,并且每个数据都有它自己的方式逃避数据。
让我们快速回顾一下为什么在不同情况下需要逃避:
如果您使用引号分隔字符串,则需要能够转义引号。 如果您使用的是xml,则需要将“内容”与“标记”分开 如果您使用的是SQL,则需要将“命令”与“数据”分开 如果您在命令行中,则需要将“命令”与“数据”分开
这一般是计算的一个基本方面。因为分隔数据的语法可以在数据中出现,所以需要有一种方法来区分DATA和SYNTAX,从而逃避。
在网络编程中,常见的逃避案例是: 1.将文本输出为HTML 2.将数据输出到HTML属性 3.将HTML输出为HTML 4.将数据插入Javascript 5.将数据插入SQL 6.将数据插入shell命令
如果处理不当,每个人都会有不同的安全隐患。这真的很重要!让我们在PHP的背景下回顾一下:
将文字转换为HTML: 用htmlspecialchars(...)
数据到HTML属性 htmlspecialchars(...,ENT_QUOTES)
HTML转换为HTML 使用HTMLPurifier等库来确保只存在有效标记。
将数据导入Javascript
我更喜欢json_encode
。如果要将其放在属性中,则仍需要使用#2,例如
将数据插入SQL 每个驱动程序都有某种类型的escape()函数。这是最好的。如果您使用普通的latin1字符集运行,则addslashes(...)是合适的。不要忘记引号AROUND addslashes()调用:
“INSERT INTO table1 SET field1 ='”。 addslashes($ data)。 “'”
命令行上的数据 escapeshellarg()和escapeshellcmd() - 阅读手册
- 牢记这些,您将消除95%*的常见网络安全风险! (*猜测)
答案 1 :(得分:3)
如果您的$_REQUEST
中有数组,则其值不会被清理。
答案 2 :(得分:3)
我已经制作并使用了这个:
<?php
function _clean($var){
$pattern = array("/0x27/","/%0a/","/%0A/","/%0d/","/%0D/","/0x3a/",
"/union/i","/concat/i","/delete/i","/truncate/i","/alter/i","/information_schema/i",
"/unhex/i","/load_file/i","/outfile/i","/0xbf27/");
$value = addslashes(preg_replace($pattern, "", $var));
return $value;
}
if(isset($_GET)){
foreach($_GET as $k => $v){
$_GET[$k] = _clean($v);
}
}
if(isset($_POST)){
foreach($_POST as $k => $v){
$_POST[$k] = _clean($v);
}
}
?>
答案 3 :(得分:2)
您的方法会尝试清理所有请求数据以插入数据库,但是如果您只是想输出它呢?输出中会有不必要的反斜杠。此外,无论如何,转义不是防止SQL异常的好策略。通过使用参数化查询(例如在PDO或MySQLi中),您将“转义”问题“传递”到抽象层。
答案 4 :(得分:2)
除了没有递归到数组和不必要的转换,例如整数之外,这种方法在清理之前编码用于SQL语句的数据。 mysql_real_escape_string()
逃避数据,它没有消毒它 - 逃避和消毒不是一回事。
清理是许多PHP脚本在使用之前仔细检查输入数据的可接受性的任务。我认为对未转义的数据做得更好。在进入SQL之前,我通常不会转义数据。那些喜欢使用Prepared Statements的人会这样做。
还有一件事:如果输入数据可以包含utf8字符串,那么它们似乎应该在转义之前进行验证。我经常在清理之前在$ _POST上使用递归的utf8清理器。