Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP/MYSQL:清理用户输入-这是个坏主意吗?_Php_Mysql_Sanitization - Fatal编程技术网

PHP/MYSQL:清理用户输入-这是个坏主意吗?

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

我有一个“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,则需要将“命令”与“数据”分开 如果在命令行上,则需要将“命令”与“数据”分开

这是计算的一个基本方面。因为分隔数据的语法可能出现在数据中,所以需要有一种方法将数据与语法区分开来,从而进行转义

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

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

  • 将文本转换为HTML: htmlspecialchars(…)

  • 将数据转换为HTML属性 htmlspecialchars(…,ENT_引号)

  • HTML转换为HTML 使用库(如)确保只存在有效的标记

  • 将数据转换为Javascript 我更喜欢json编码。如果要将其放置在属性中,仍然需要使用#2,例如

  • 将数据插入SQL 每个驱动程序都有某种类型的escape()函数。这是最好的。如果您使用的是普通拉丁1字符集,则addslashes(…)是合适的。不要忘记addslashes()调用周围的引号:

    “插入到表1集合字段1=”。addslashes($data)。“'”

  • 命令行上的数据 escapeshellarg()和escapeshellcmd()--阅读手册

  • --
    牢记这些,您将消除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时做了哪些不同之处?