繁体   English   中英

PHP / MYSQL:消除用户输入 - 这是一个坏主意吗?

[英]PHP / MYSQL: Sanitizing user input - is this a bad idea?

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

我发现在使用数据时逃避数据要好得多,而不是在进行中。您可能希望在JSON,XML,Shell,MySQL,Curl或HTML中使用这些数据,并且每个数据都有自己的方式。逃避数据。


让我们快速回顾一下为什么在不同的环境中需要逃避:

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

这一般是计算的一个基本方面。 因为分隔数据的语法可以在数据中出现,所以需要有一种方法来区分DATA和SYNTAX,从而逃避。

在Web编程中,常见的转义案例是: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(...)是合适的。 不要忘记引号AROUND addslashes()调用:

    “INSERT INTO table1 SET field1 ='”。 addslashes($ data)。 “'”

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

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

如果$_REQUEST有数组,则它们的值将不会被清理。

我已经制作并使用了这个:

<?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);
    }
}
?>

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

除了没有递归到数组和不必要的转换,例如整数之外,这种方法在清理之前编码用于SQL语句的数据。 mysql_real_escape_string()转义数据,它不会消毒它 - 转义和消毒不是一回事。

清理是许多PHP脚本在使用之前仔细检查输入数据的可接受性的任务。 我认为对未转义的数据做得更好。 在进入SQL之前,我通常不会转义数据。 那些喜欢使用预备语句的人就是这样做的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM