是否存在一种万能函数,可以很好地为SQL注入和XSS攻击清除用户输入,同时仍然允许某些类型的HTML标记?


当前回答

不,没有。

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

基本经验法则

对于SQL查询,绑定参数 使用strip_tags()过滤掉不需要的HTML 使用htmlspecialchars()转义所有其他输出,并注意这里的第2和第3个参数。

其他回答

有一个技巧可以帮助您在特定情况下使用/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
}

但当然,这只排除了一个特定的攻击,所以阅读所有其他的答案。(是的,我知道上面的代码不是很好,但它显示了具体的防御。)

认为用户输入可以过滤是一种常见的误解。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标记。但是,您应该明智地不惜一切代价避免这种情况,因为无论您如何过滤它,它始终是一个潜在的安全漏洞。

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

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

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

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

PHP 5.2引入了filter_var函数。

它支持大量的SANITIZE, VALIDATE过滤器。