PHP/MYSQL:清理用户输入-这是个坏主意吗?
我有一个“go”脚本,用于获取任何其他请求的脚本,这是我为清理用户输入而编写的:PHP/MYSQL:清理用户输入-这是个坏主意吗?,php,mysql,sanitization,Php,Mysql,Sanitization,我有一个“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
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);
}
我发现最好是在使用数据时逃逸数据,而不是在输入数据时逃逸。您可能希望在JSON、XML、Shell、MySQL、Curl或HTML中使用这些数据,并且每个数据都有自己的转义方式
让我们快速回顾一下为什么在不同的上下文中需要转义: 如果处于引号分隔的字符串中,则需要能够转义引号。 如果使用xml,则需要将“内容”与“标记”分开 如果使用SQL,则需要将“命令”与“数据”分开 如果在命令行上,则需要将“命令”与“数据”分开 这是计算的一个基本方面。因为分隔数据的语法可能出现在数据中,所以需要有一种方法将数据与语法区分开来,从而进行转义 在web编程中,常见的转义情况有: 1.将文本输出为HTML 2.将数据输出到HTML属性中 3.将HTML输出为HTML 4.将数据插入Javascript 5.将数据插入SQL 6.将数据插入shell命令 如果处理不当,每一个都有不同的安全含义。这真的很重要!让我们在PHP的上下文中回顾一下:
牢记这些,您将消除95%*的常见网络安全风险!(*猜测)您的方法尝试清理所有请求数据,以便插入到数据库中,但是如果您只是想输出它呢?输出中将有不必要的反斜杠。此外,无论如何,转义并不是防止SQL异常的好策略。通过使用参数化查询(例如在PDO或MySQLi中),您可以“传递”转义到抽象层的问题。如果您的
$\u请求中有数组,它们的值将不会被清除。除了缺少对数组的递归和不必要的转义(例如整数)之外,这种方法在清理之前对SQL语句中使用的数据进行编码<代码>mysql\u real\u escape\u string()
转义数据,它不会对数据进行清理--转义和清理不是一回事
清理是许多PHP脚本在使用输入数据之前必须仔细检查其可接受性的任务。我认为这是更好的数据还没有逃脱。在数据进入SQL之前,我通常不会转义数据。那些喜欢使用这种方法的人也能达到同样的效果
还有一件事:若输入数据可以包含utf8字符串,那个么在转义之前似乎应该验证这些字符串。在消毒之前,我经常在$\u POST上使用递归utf8清洁剂。我制作并使用了这个:
<?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);
}
}
?>
不幸的是,我的字符集是UTF-8,不限于拉丁字符。我已经把它写下来了,这样所有的内容都能正确地转义,但我想我只是过于偏执了,我会留下一些SQL注入的漏洞。mysql_real_escape_字符是清理进入数据库的用户输入的更好选择。这是一个很好的建议,存储原始表示,然后以适合介质的方式对其进行转义。或者,您可以像我们这样存储这两种表示。但无论你做什么,都要保留原始版本,否则你会后悔的——相信我。+1是一个清晰的逐案解决方案。如果您也能在案例3和案例4上提供一个纯PHP解决方案,那就更好了。@Greg,您在使用UTF-8时做了哪些不同之处?