如何使用PHP清理用户输入?


1124

是否有某个功能全面的功能可以很好地用于清理用户对SQL注入和XSS攻击的输入,同时仍然允许某些类型的HTML标签?


42
如今,为了避免SQL注入,请使用PDO或MySQLi。
Francisco Presencia

76
仅使用PDO或MySQLi是不够的。如果您使用不受信任的数据(例如)构建SQL语句select * from users where name='$name',则使用PDO还是MySQLi或MySQL都没有关系。您仍然处于危险之中。您必须使用参数化查询,或者,如果需要,请对数据使用转义机制,但这是不太可取的。
安迪·莱斯特

26
@AndyLester您是否暗示某人在没有准备好的语句的情况下使用PDO?:)

63
我是说“使用PDO或MySQLi”不足以向新手解释如何安全使用它们。您和我知道准备好的陈述很重要,但我不认为阅读此问题的每个人都会知道。这就是为什么我添加了明确的说明。
安迪·莱斯特

30
安迪的评论完全正确。我最近将mysql网站转换为PDO,以为我现在可以免受注入攻击。只是在此过程中,我才意识到我的某些sql语句仍是使用用户输入来构建的。然后,我使用准备好的语句修复了该问题。对于一个新手来说,尚不清楚是否存在区别,因为许多专家对使用PDO都发表了评论,但没有指定需要准备好的语句。假设是显而易见的。但不是新手。
GhostRider 2014年

Answers:


1183

常见的误解是可以过滤用户输入。PHP甚至有一个(现在已弃用的)“功能”,称为magic-quotes,它基于此思想。废话 忘记过滤(或清洁,或任何人称呼它)。

为避免出现问题,您应该做的事情很简单:每当将字符串嵌入外部代码中时,都必须根据该语言的规则对其进行转义。例如,如果您在针对MySQL的某些SQL中嵌入了字符串,则必须为此使用MySQL的函数对字符串进行转义(mysqli_real_escape_string)。(或者,对于数据库,在可能的情况下,使用预备语句是更好的方法。)

另一个示例是HTML:如果将字符串嵌入HTML标记中,则必须使用对其进行转义htmlspecialchars。这意味着每个单行echoprint语句应使用htmlspecialchars

第三个示例是shell命令:如果要将字符串(例如参数)嵌入到外部命令中,并使用调用它们exec,则必须使用escapeshellcmdescapeshellarg

等等等等 ...

您需要主动过滤数据的唯一情况是接受预先格式化的输入。例如,如果您让用户发布HTML标记,那么您计划显示在网站上。但是,您应该明智地不惜一切代价避免这种情况,因为无论您对其进行多么好的过滤,它始终都是潜在的安全漏洞。


245
“这意味着每个回显或打印语句都应使用htmlspecialchars”-当然,您的意思是“每个...语句都输出用户输入”;htmlspecialchars()-表示“回声'你好,世界!';” 会很疯狂;)
鲍比·杰克

10
在一种情况下,我认为过滤是正确的解决方案:UTF-8。您不希望整个应用程序中都存在无效的UTF-8序列(根据代码路径可能会得到不同的错误恢复),并且可以轻松地过滤(或拒绝)UTF-8。
Kornel

6
@jbyrd-不,LIKE使用专用的正则表达式语言。您将必须对输入字符串进行两次转义-一次用于regexp,一次用于mysql字符串编码。它是代码内的代码。
troelskn 2011年

6
此刻mysql_real_escape_string已过时。如今,使用准备好的语句来防止SQL注入被认为是一种好习惯。因此,切换到MySQLi或PDO。
Marcel Korpel 2013年

4
因为您限制了攻击面。如果尽早(输入时)进行消毒,则必须确保应用程序中没有其他漏洞可以进入不良数据的漏洞。而如果您迟到了,那么您的输出函数就不必“相信”已获得安全数据,它只是假设一切都不安全。
troelskn 2014年

217

不要尝试通过清除输入数据来防止SQL注入。

相反,请勿在创建SQL代码时使用数据。使用使用绑定变量的预处理语句(即在模板查询中使用参数)。这是防止SQL注入的唯一方法。

请访问我的网站http://bobby-tables.com/了解更多有关防止SQL注入的信息。


18
或访问官方文档并了解PDO和准备好的声明。很小的学习曲线,但是如果您非常了解SQL,那么您就可以轻松适应。
的编码员

2
对于SQL注入的特定情况,是正确的答案!
Scott Arciszewski 2015年

4
请注意,准备好的语句不会增加任何安全性,而参数化查询会增加任何安全性。它们恰好很容易在PHP中一起使用。
基本

这不是唯一保证的方法。十六进制输入和查询中的十六进制也会阻止输入。如果正确使用hexing,也无法进行hex攻击。
拉蒙·巴克

如果您要输入一些专业的信息,例如电子邮件地址或用户名,该怎么办?
亚伯拉罕·布鲁克斯

78

不可以。没有任何用途的通用上下文,您就无法过滤数据。有时您希望将SQL查询作为输入,有时希望将HTML作为输入。

您需要过滤白名单上的输入-确保数据符合您所期望的某种规格。然后,您需要在使用它之前对其进行转义,具体取决于您所使用的上下文。

为SQL转义数据以防止SQL注入的过程与为(X)HTML转义数据以防止XSS的过程非常不同。


52

PHP现在有了新的漂亮的filter_input函数,例如,由于内置了FILTER_VALIDATE_EMAIL类型,因此使您不必再寻找“最终的电子邮件正则表达式”

我自己的过滤器类(使用JavaScript突出显示错误的字段)可以通过ajax请求或常规表单发布来启动。(请参见下面的示例)

/**
 *  Pork.FormValidator
 *  Validates arrays or properties by setting up simple arrays. 
 *  Note that some of the regexes are for dutch input!
 *  Example:
 * 
 *  $validations = array('name' => 'anything','email' => 'email','alias' => 'anything','pwd'=>'anything','gsm' => 'phone','birthdate' => 'date');
 *  $required = array('name', 'email', 'alias', 'pwd');
 *  $sanitize = array('alias');
 *
 *  $validator = new FormValidator($validations, $required, $sanitize);
 *                  
 *  if($validator->validate($_POST))
 *  {
 *      $_POST = $validator->sanitize($_POST);
 *      // now do your saving, $_POST has been sanitized.
 *      die($validator->getScript()."<script type='text/javascript'>alert('saved changes');</script>");
 *  }
 *  else
 *  {
 *      die($validator->getScript());
 *  }   
 *  
 * To validate just one element:
 * $validated = new FormValidator()->validate('blah@bla.', 'email');
 * 
 * To sanitize just one element:
 * $sanitized = new FormValidator()->sanitize('<b>blah</b>', 'string');
 * 
 * @package pork
 * @author SchizoDuckie
 * @copyright SchizoDuckie 2008
 * @version 1.0
 * @access public
 */
class FormValidator
{
    public static $regexes = Array(
            'date' => "^[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{4}\$",
            'amount' => "^[-]?[0-9]+\$",
            'number' => "^[-]?[0-9,]+\$",
            'alfanum' => "^[0-9a-zA-Z ,.-_\\s\?\!]+\$",
            'not_empty' => "[a-z0-9A-Z]+",
            'words' => "^[A-Za-z]+[A-Za-z \\s]*\$",
            'phone' => "^[0-9]{10,11}\$",
            'zipcode' => "^[1-9][0-9]{3}[a-zA-Z]{2}\$",
            'plate' => "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}\$",
            'price' => "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?\$",
            '2digitopt' => "^\d+(\,\d{2})?\$",
            '2digitforce' => "^\d+\,\d\d\$",
            'anything' => "^[\d\D]{1,}\$"
    );
    private $validations, $sanatations, $mandatories, $errors, $corrects, $fields;


    public function __construct($validations=array(), $mandatories = array(), $sanatations = array())
    {
        $this->validations = $validations;
        $this->sanitations = $sanitations;
        $this->mandatories = $mandatories;
        $this->errors = array();
        $this->corrects = array();
    }

    /**
     * Validates an array of items (if needed) and returns true or false
     *
     */
    public function validate($items)
    {
        $this->fields = $items;
        $havefailures = false;
        foreach($items as $key=>$val)
        {
            if((strlen($val) == 0 || array_search($key, $this->validations) === false) && array_search($key, $this->mandatories) === false) 
            {
                $this->corrects[] = $key;
                continue;
            }
            $result = self::validateItem($val, $this->validations[$key]);
            if($result === false) {
                $havefailures = true;
                $this->addError($key, $this->validations[$key]);
            }
            else
            {
                $this->corrects[] = $key;
            }
        }

        return(!$havefailures);
    }

    /**
     *
     *  Adds unvalidated class to thos elements that are not validated. Removes them from classes that are.
     */
    public function getScript() {
        if(!empty($this->errors))
        {
            $errors = array();
            foreach($this->errors as $key=>$val) { $errors[] = "'INPUT[name={$key}]'"; }

            $output = '$$('.implode(',', $errors).').addClass("unvalidated");'; 
            $output .= "new FormValidator().showMessage();";
        }
        if(!empty($this->corrects))
        {
            $corrects = array();
            foreach($this->corrects as $key) { $corrects[] = "'INPUT[name={$key}]'"; }
            $output .= '$$('.implode(',', $corrects).').removeClass("unvalidated");';   
        }
        $output = "<script type='text/javascript'>{$output} </script>";
        return($output);
    }


    /**
     *
     * Sanitizes an array of items according to the $this->sanitations
     * sanitations will be standard of type string, but can also be specified.
     * For ease of use, this syntax is accepted:
     * $sanitations = array('fieldname', 'otherfieldname'=>'float');
     */
    public function sanitize($items)
    {
        foreach($items as $key=>$val)
        {
            if(array_search($key, $this->sanitations) === false && !array_key_exists($key, $this->sanitations)) continue;
            $items[$key] = self::sanitizeItem($val, $this->validations[$key]);
        }
        return($items);
    }


    /**
     *
     * Adds an error to the errors array.
     */ 
    private function addError($field, $type='string')
    {
        $this->errors[$field] = $type;
    }

    /**
     *
     * Sanitize a single var according to $type.
     * Allows for static calling to allow simple sanitization
     */
    public static function sanitizeItem($var, $type)
    {
        $flags = NULL;
        switch($type)
        {
            case 'url':
                $filter = FILTER_SANITIZE_URL;
            break;
            case 'int':
                $filter = FILTER_SANITIZE_NUMBER_INT;
            break;
            case 'float':
                $filter = FILTER_SANITIZE_NUMBER_FLOAT;
                $flags = FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND;
            break;
            case 'email':
                $var = substr($var, 0, 254);
                $filter = FILTER_SANITIZE_EMAIL;
            break;
            case 'string':
            default:
                $filter = FILTER_SANITIZE_STRING;
                $flags = FILTER_FLAG_NO_ENCODE_QUOTES;
            break;

        }
        $output = filter_var($var, $filter, $flags);        
        return($output);
    }

    /** 
     *
     * Validates a single var according to $type.
     * Allows for static calling to allow simple validation.
     *
     */
    public static function validateItem($var, $type)
    {
        if(array_key_exists($type, self::$regexes))
        {
            $returnval =  filter_var($var, FILTER_VALIDATE_REGEXP, array("options"=> array("regexp"=>'!'.self::$regexes[$type].'!i'))) !== false;
            return($returnval);
        }
        $filter = false;
        switch($type)
        {
            case 'email':
                $var = substr($var, 0, 254);
                $filter = FILTER_VALIDATE_EMAIL;    
            break;
            case 'int':
                $filter = FILTER_VALIDATE_INT;
            break;
            case 'boolean':
                $filter = FILTER_VALIDATE_BOOLEAN;
            break;
            case 'ip':
                $filter = FILTER_VALIDATE_IP;
            break;
            case 'url':
                $filter = FILTER_VALIDATE_URL;
            break;
        }
        return ($filter === false) ? false : filter_var($var, $filter) !== false ? true : false;
    }       



}

当然,请记住,您也需要根据所使用的数据库类型来转义sql查询(例如,对于SQL Server,mysql_real_escape_string()是无用的)。您可能希望在适当的应用程序层(如ORM)自动处理此问题。另外,如上所述:要输出到html,请使用其他php专用功能,例如htmlspecialchars;)

要真正允许使用类似剥离的类和/或标签的HTML输入,取决于专用的xss验证程序包之一。不要写自己的正则表达式来解析HTML!


17
看起来这可能是用于验证输入的便捷脚本,但与该问题完全无关。
rjmunro 2011年

43

不,那里没有。

首先,SQL注入是一个输入过滤问题,而XSS是一个转义输出的问题-因此,您甚至都不会在代码生命周期中同时执行这两个操作。

基本经验法则

  • 对于SQL查询,请绑定参数(与PDO一样)或对查询变量使用驱动程序本机转义函数(例如mysql_real_escape_string()
  • 使用strip_tags()过滤掉不需要的HTML
  • 请使用htmlspecialchars()此处的第二和第三参数来转义所有其他输出。

1
因此,仅当您知道输入包含要分别删除或转义的HTML时,才使用strip_tags()或htmlspecialchars()-您不是出于安全目的使用它吗?另外,当您进行绑定时,它对Bobby Tables之类的东西有什么作用?“罗伯特(Robert));下降表学生;-”“它只是逃避引号吗?
罗伯·马克·布拉姆

2
如果您有将要进入数据库并随后在网页上显示的用户数据,通常它读取的内容比书写的内容多得多吗?对我来说,在存储之前对其进行一次过滤(作为输入)比较有意义,而不是每次显示时都对其进行过滤。我是否缺少某些东西,或者是否有人在此和公认的答案中投票给不必要的性能开销?
jbo5112

2
对我来说最好的答案。简短,如果您问我,这个问题很好解决。是否可以通过$ _POST或$ _GET注入某种方式来攻击PHP,或者这是不可能的?
Jo Smo 2014年

哦,是的,$ post和$ get数组接受所有字符,但是如果允许在发布的php页面中枚举该字符,则可以对其中一些字符使用。因此,如果您不逃避封装字符(例如“,”和`),则可能会打开攻击向量。通常会漏掉`字符,并可用于形成命令行执行黑客程序。卫生措施可防止用户输入黑客程序,但不会帮助您解决Web应用程序防火墙黑客问题
drtechno

22

要解决XSS问题,请看HTML Purifier。它是相当可配置的,并且具有良好的记录。

至于SQL注入攻击,请确保检查用户输入,然后通过mysql_real_escape_string()运行它。但是,该函数不会克服所有注入攻击,因此,在将数据转储到查询字符串之前,请先检查数据,这一点很重要。

更好的解决方案是使用准备好的语句。该PDO库和mysqli扩展支持这些。


没有“最好的方法”来进行诸如清除输入内容之类的操作。这些库已被多次使用。因此,它比您自己想出的任何东西都更具防弹能力
Paan


wordpress的问题在于它不一定是导致数据库破坏的php-sql注入攻击。缺少存储xml查询揭示秘密的数据的已编程程序员插件,则存在更多问题。
drtechno


17

在特定的情况下(例如,您拥有一个页面,/mypage?id=53并且您在WHERE子句中使用id)可以帮助您解决问题的一个技巧是,确保id绝对是整数,例如:

if (isset($_GET['id'])) {
  $id = $_GET['id'];
  settype($id, 'integer');
  $result = mysql_query("SELECT * FROM mytable WHERE id = '$id'");
  # now use the result
}

但是,当然,这只会消除一种特定的攻击,因此请阅读所有其他答案。(是的,我知道上面的代码不是很好,但是它显示了特定的防御。)


11
我改用$ id = intval($ id):)
Duc Tran

强制转换整数是确保仅插入数字数据的好方法。
测试

1
$id = (int)$_GET['id']而且$que = sprintf('SELECT ... WHERE id="%d"', $id)也很好
vladkras

16

使用PHP清理用户输入的方法:

  • 使用MySQL和PHP的现代版本。

  • 显式设置字符集:

    • $ mysqli-> set_charset(“ utf8”);
      手册
    • $ pdo =新的PDO('mysql:host = localhost; dbname = testdb; charset = UTF8',$ user,$ password);
      手册
    • $ pdo-> exec(“设置名称utf8”);
      手册
    • $ pdo =新的PDO(
      “ mysql:host = $ host; dbname = $ db”,$ user,$ pass, 
      数组(
      PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION,
      PDO :: MYSQL_ATTR_INIT_COMMAND =>“设置名称utf8”
      )
      );
      手册
    • mysql_set_charset('utf8')
      [在PHP 5.5.0中已弃用,在PHP 7.0.0中已删除]。
  • 使用安全字符集:

    • 选择utf8,latin1,ascii ..,请勿使用易受攻击的字符集big5,cp932,gb2312,gbk,sjis。
  • 使用空间化功能:

    • MySQLi准备的语句:
      $ stmt = $ mysqli-> prepare('SELECT * FROM test WHERE name =?LIMIT 1'); 
      $ param =“'OR 1 = 1 / *”;
      $ stmt-> bind_param('s',$ param);
      $ stmt-> execute();
    • PDO :: quote() -使用适合底层驱动程序的引号样式将引号放在输入字符串(如果需要)周围,并在输入字符串内转义特殊字符:

      $ pdo =新的PDO('mysql:host = localhost; dbname = testdb; charset = UTF8',$ user,$ password); 显式设置字符集
      $ pdo-> setAttribute(PDO :: ATTR_EMULATE_PREPARES,false); 禁用模拟准备好的语句以防止回
      退到模拟MySQL不能自然准备的语句(以防止注入) $ var = $ pdo-> quote(“'OR 1 = 1 / *”); 不仅转义字面量,还用单引号'字符将其引起来 $ stmt = $ pdo-> query(“ SELECT * FROM test WHERE name = $ var LIMIT 1”);

    • PDO准备语句:vs MySQLi准备语句支持更多的数据库驱动程序和命名参数:

      $ pdo =新的PDO('mysql:host = localhost; dbname = testdb; charset = UTF8',$ user,$ password); 显式设置字符集
      $ pdo-> setAttribute(PDO :: ATTR_EMULATE_PREPARES,false); 禁用模拟准备好的语句,以防止回退到模拟MySQL无法本地准备的语句(以防止注入) $ stmt = $ pdo-> prepare('SELECT * FROM test WHERE name =?LIMIT 1'); $ stmt-> execute([“'OR 1 = 1 / *”]);

    • mysql_real_escape_string [在PHP 5.5.0中已弃用,在PHP 7.0.0中已删除]。
    • mysqli_real_escape_string考虑到连接的当前字符集,转义字符串中的特殊字符以供SQL语句使用。但是建议使用Prepared Statements,因为它们不是简单的转义字符串,它提供了完整的查询执行计划,包括它将使用的表和索引,这是一种优化的方式。
    • 在查询中的变量周围使用单引号('')。
  • 检查变量是否包含您的期望:

    • 如果期望整数,请使用:
      ctype_digit —检查数字字符;
      $ value =(int)$ value;
      $ value = intval($ value);
      $ var = filter_var('0755',FILTER_VALIDATE_INT,$ options);
    • 对于字符串,请使用:
      is_string()—查找变量的类型是否为字符串

      Use Filter Function filter_var()—使用指定的过滤器过滤变量:
      $ email = filter_var($ email,FILTER_SANITIZE_EMAIL); 
      $ newstr = filter_var($ str,FILTER_SANITIZE_STRING);
      更多预定义的过滤器
    • filter_input() —按名称获取特定的外部变量,并可以选择对其进行过滤:
      $ search_html = filter_input(INPUT_GET,'search',FILTER_SANITIZE_SPECIAL_CHARS);
    • preg_match() —执行正则表达式匹配;
    • 编写您自己的验证功能。

11

您在这里描述的是两个独立的问题:

  1. 消毒/过滤用户输入数据。
  2. 转义输出。

1)用户输入总是被认为是错误的。

绝对必须使用准备好的语句,或者使用mysql_real_escape_string进行过滤。PHP还内置了filter_input,这是一个不错的起点。

2)这是一个很大的主题,它取决于输出数据的上下文。对于HTML,有诸如htmlpurifier之类的解决方案。根据经验,始终不要输出任何内容。

这两个问题都太大了,无法在一个帖子中讨论,但是有很多帖子更详细:

方法PHP输出

更安全的PHP输出



8

没有包罗万象的功能,因为有多个问题需要解决。

  1. SQL注入 -如今,通常,每个PHP项目都应通过PHP数据对象(PDO)使用预先准备好的语句,这是最佳实践,可防止因引号引起的错误以及针对注入的全功能解决方案。这也是访问数据库的最灵活,最安全的方法。

    查看(唯一的)PDO教程,了解有关PDO所需的几乎所有知识。(衷心感谢顶级SO杰出贡献者@YourCommonSense,感谢他在这一主题上的宝贵资源。)

  2. XSS-清理中途的数据

    • HTML Purifier已经存在了很长时间,并且仍在积极更新中。您可以使用它来清理恶意输入,同时仍然允许大量且可配置的标签白名单。在许多WYSIWYG编辑器中都可以很好地工作,但是在某些用例中可能会很繁重。

    • 在其他情况下,我们根本不想接受HTML / Javascript,我发现这个简单的功能很有用(并且已经通过了针对XSS的多次审核):

      /* Prevent XSS input */ function sanitizeXSS () { $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); $_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST; }

  3. XSS-清理输出中的数据...除非您保证在将数据添加到数据库之前已对它们进行了正确的清理,否则需要在将其显示给用户之前对其进行清理,我们可以利用以下有用的PHP函数:

    • 当您调用echoprint显示用户提供的值时,请使用htmlspecialchars该数据,除非对数据进行了正确的安全清理并允许显示HTML。
    • json_encode 是从PHP到Javascript提供用户提供的值的安全方法
  4. 您是使用exec()还是system()函数调用外部外壳命令,还是要调用backtick操作员?如果是这样,除了SQL Injection&XSS之外,您可能还需要解决在服务器上运行恶意命令的用户escapeshellcmd如果要转义整个命令或escapeshellarg转义单个参数,则需要使用。


可以改用mb_encode_numericentity吗?既然可以编码所有内容?
drtechno

@drtechno- 在#3 XSS mb_encode_numericentityhtmlspecialchars链接中进行了讨论
webaholik '19

5

避免在清理输入和转义数据时出错的最简单方法是使用PHP框架(如SymfonyNette等)或该框架的一部分(模板引擎,数据库层,ORM)。

Twig或Latte 这样的模板引擎默认情况下会转义输出-如果您根据上下文(网页的HTML或Javascript部分)正确地转义了输出,则无需手动解决。

框架会自动清理输入,您不应直接使用$ _POST,$ _ GET或$ _SESSION变量,而应通过路由,会话处理等机制使用。

对于数据库(模型)层,存在像Doctrine这样的ORM框架,或者像Nette Database这样围绕PDO的包装器。

您可以在此处了解更多信息- 什么是软件框架?


3

只是想在输出转义的主题上添加它,如果您使用php DOMDocument进行html输出,它将在正确的上下文中自动转义。属性(value =“”)和<span>的内部文本不相等。为了安全防范XSS,请阅读以下内容: OWASP XSS预防备忘单


2

您永远不会清除输入。

您总是要清理输出。

您应用于数据以使其可以安全地包含在SQL语句中的转换与您申请包含在HTML中的转换完全不同,不同于您申请包含在Javascript中的转换与您申请包含在LDIF中的转换完全不同。与您申请包含在CSS中的完全不同。

通过一切手段验证输入 -决定你是否应该接受它作进一步处理或告知这是不能接受的用户。但是,在数据将要离开PHP之前,请不要对数据的表示进行任何更改。

很久以前,有人试图发明一种适用于所有数据转义的全尺寸机制,而我们最终得到了“ magic_quotes ”,它不能正确地为所有输出目标转义数据,并导致安装不同需要使用不同的代码。


这样做的一个问题是,它并不总是受到数据库的攻击,应该保护所有用户的输入不受系统的攻击。不只是一种语言。因此,在您的站点上,当枚举$ _POST数据时,即使使用绑定,它也可能逃脱出足以执行Shell甚至其他php代码的空间。
drtechno

“它并不总是发生数据库攻击”:“您应用于数据以使其安全地包含在SQL语句中的转换与那些完全不同....”
symcbean

“应保护所有用户输入不受系统的影响”:不应保护系统不受用户输入的影响。
symcbean

好吧,我没话说了,但是是的,需要防止输入影响系统操作。为了澄清这一点...
drtechno

输入和输出均应进行消毒。
塔吉尼

1

永远不要信任用户数据。

function clean_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}

trim()函数从字符串的两侧删除空格和其他预定义字符。

stripslashes()功能去除反斜杠

htmlspecialchars()函数将一些预定义的字符转换为HTML实体。

预定义的字符是:

& (ampersand) becomes &amp;
" (double quote) becomes &quot;
' (single quote) becomes &#039;
< (less than) becomes &lt;
> (greater than) becomes &gt;

1
这将保护什么?这是XSS吗?那为什么叫它clean_input?您为什么要去除斜线?
Dharman

4
警告:这不会神奇地确保用户数据的安全。此功能将不必要地损坏您的数据,而不会造成任何损害。不要使用它!
Dharman

您的陈述是错误的。
Erik Thiart,

0

有过滤器扩展名(howto-linkmanual),该扩展名对所有GPC变量都非常有效。尽管这不是万能的事情,您仍然必须使用它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.