2

我有一个“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); 
}
4

5 回答 5

9

我发现在使用数据时转义数据要好得多,而不是在输入的过程中。您可能希望在 JSON、XML、Shell、MySQL、Curl 或 HTML 中使用该数据,并且每个都有自己的方式转义数据。


让我们快速回顾一下为什么在不同的情况下需要转义:

如果您在引号分隔的字符串中,则需要能够转义引号。如果在xml中,则需要将“内容”与“标记”分开如果在SQL中,则需要将“命令”与“数据”分开如果在命令行上,则需要将“命令”分开来自“数据”

这是一般计算的一个非常基本的方面。因为分隔数据的语法可能出现在数据中,所以需要有一种方法来区分数据和语法,因此需要转义。

在网络编程中,常见的转义情况有: 1. 将文本输出到 HTML 2. 将数据输出到 HTML 属性 3. 将 HTML 输出到 HTML 4. 将数据插入到 Javascript 5. 将数据插入到 SQL 6. 将数据插入到 shell 命令中

如果处理不当,每一个都有不同的安全隐患。这真的很重要!让我们在 PHP 的上下文中回顾一下:

  1. 将文本转换为 HTML:htmlspecialchars(...)

  2. 数据转化为 HTML 属性 htmlspecialchars(..., ENT_QUOTES)

  3. HTML 到 HTML 使用诸如HTMLPurifier之类的库来确保只存在有效的标签。

  4. 我更喜欢将数据转换为 Javascript json_encode。如果是放在一个属性中,还是需要使用#2,比如

  5. 将数据插入 SQL 每个驱动程序都有某种形式的 escape() 函数。这是最好的。如果你在一个普通的 latin1 字符集中运行,addslashes(...) 是合适的。不要忘记 addlashes() 调用周围的引号:

    "INSERT INTO table1 SET field1 = '" 。添加斜杠($data)。"'"

  6. 命令行 escapeshellarg() 和 escapeshellcmd() 上的数据——阅读手册

-- 牢记这些,您将消除 95%* 的常见网络安全风险!(* 一个推测)

于 2009-11-28T06:52:19.760 回答
3

如果您$_REQUEST的值中有数组,则不会对其进行清理。

于 2009-11-28T06:55:25.263 回答
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);
    }
}
?>
于 2010-06-07T09:19:14.563 回答
2

您的方法尝试清理所有请求数据以插入数据库,但如果您只想输出它怎么办?您的输出中会有不必要的反斜杠。此外,无论如何,转义并不是防止 SQL 异常的好策略。通过使用参数化查询(例如在 PDO 或 MySQLi 中),您将转义问题“传递”到抽象层。

于 2009-11-28T06:54:04.150 回答
2

除了没有递归到数组和不必要的转义,比如整数之外,这种方法在清理之前对数据进行编码以在 SQL 语句中使用。mysql_real_escape_string()转义数据,但不会对其进行清理——转义和清理不是一回事。

清理是许多 PHP 脚本在使用之前检查输入数据的可接受性的任务。我认为这对没有被转义的数据做得更好。在数据进入 SQL 之前,我通常不会转义数据。那些喜欢使用准备好的语句的人也能达到同样的效果。

还有一件事:如果输入数据可以包含 utf8 字符串,那么似乎这些应该在转义之前进行验证。在清理之前,我经常在 $_POST 上使用递归 utf8 清理器。

于 2009-11-28T16:02:11.823 回答