是否存在一种万能函数,可以很好地为SQL注入和XSS攻击清除用户输入,同时仍然允许某些类型的HTML标记?
当前回答
不要试图通过清除输入数据来防止SQL注入。
相反,不允许在创建SQL代码时使用数据。使用使用绑定变量的预制语句(即在模板查询中使用参数)。这是防止SQL注入的唯一方法。
有关防止SQL注入的更多信息,请访问我的网站http://bobby-tables.com/。
其他回答
你从不清理输入。
你总是要清理输出。
你应用到数据的转换,使其能够安全地包含在SQL语句中,完全不同于你在HTML中应用的转换,完全不同于你在Javascript中应用的转换,完全不同于你在LDIF中应用的转换,完全不同于你应用到CSS中的转换,完全不同于你应用到Email....中的转换
务必验证输入——决定您是否应该接受它进行进一步处理,还是告诉用户它是不可接受的。但是不要对数据的表示进行任何更改,直到它离开PHP为止。
很久以前,有人试图发明一种适合所有人的机制来转义数据,我们最终使用了“magic_quotes”,它不能正确地转义所有输出目标的数据,导致不同的安装需要不同的代码才能工作。
认为用户输入可以过滤是一种常见的误解。PHP甚至有一个(现在已弃用)“特征”,被称为魔术引号,建立在这个想法上。这是无稽之谈。忘记过滤(或清洗,或人们所说的任何东西)。
What you should do, to avoid problems, is quite simple: whenever you embed a a piece of data within a foreign code, you must treat it according to the formatting rules of that code. But you must understand that such rules could be too complicated to try to follow them all manually. For example, in SQL, rules for strings, numbers and identifiers are all different. For your convenience, in most cases there is a dedicated tool for such an embedding. For example, when you need to use a PHP variable in the SQL query, you have to use a prepared statement, that will take care of all the proper formatting/treatment.
另一个例子是HTML:如果你在HTML标记中嵌入字符串,你必须使用htmlspecialchars来转义它。这意味着每个echo或print语句都应该使用htmlspecialchars。
第三个例子可能是shell命令:如果您打算将字符串(如参数)嵌入到外部命令中,并使用exec调用它们,那么您必须使用escapeshellcmd和escapeshellarg。
还有一个非常引人注目的例子是JSON。规则是如此之多和复杂,你永远无法手动遵循它们。这就是为什么你永远不应该手动创建JSON字符串,而总是使用一个专门的函数,json_encode(),它将正确地格式化每一位数据。
诸如此类……
您需要主动过滤数据的唯一情况是,如果您接受预格式化的输入。例如,如果您让用户发布您计划在站点上显示的HTML标记。但是,您应该明智地不惜一切代价避免这种情况,因为无论您如何过滤它,它始终是一个潜在的安全漏洞。
要解决XSS问题,可以看看HTML Purifier。它具有相当的可配置性和良好的记录。
对于SQL注入攻击,解决方案是使用准备好的语句。PDO库和mysqli扩展支持这些功能。
避免在清理输入和转义数据时出错的最简单方法是使用Symfony、Nette等PHP框架或该框架的一部分(模板引擎、数据库层、ORM)。
像Twig或Latte这样的模板引擎默认有输出转义-如果你根据上下文(HTML或Javascript部分的网页)正确地转义了你的输出,你不必手动解决。
框架会自动清理输入,你不应该直接使用$_POST, $_GET或$_SESSION变量,而是通过路由,会话处理等机制。
对于数据库(模型)层,有像Doctrine这样的ORM框架或围绕PDO的包装器,如Nette database。
你可以在这里阅读更多关于它的内容-什么是软件框架?
PHP 5.2引入了filter_var函数。
它支持大量的SANITIZE, VALIDATE过滤器。