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


当前回答

你所描述的是两个独立的问题:

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

1)用户输入应该总是被认为是糟糕的。

使用准备语句,或/和使用mysql_real_escape_string进行过滤绝对是必须的。 PHP还内置了filter_input,这是一个很好的开始。

2)这是一个很大的主题,它取决于输出数据的上下文。对于HTML,有一些解决方案,比如htmlpurifier。 作为经验法则,总是对输出的任何内容进行转义。

这两个问题都太大了,无法在一篇文章中详细讨论,但有很多文章会更详细地介绍:

PHP输出

更安全的PHP输出

其他回答

不。你不能在没有任何上下文的情况下过滤数据。有时你想把SQL查询作为输入,有时你想把HTML作为输入。

您需要筛选白名单上的输入——确保数据符合您所期望的某些规范。然后,您需要在使用它之前对它进行转义,这取决于您使用它的上下文。

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

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

如果你使用的是PostgreSQL, PHP的输入可以用pg_escape_literal()进行转义

$username = pg_escape_literal($_POST['username']);

从文档中可以看到:

pg_escape_literal()转义用于查询PostgreSQL数据库的字面值。它返回PostgreSQL格式的转义文本。

你从不清理输入。

你总是要清理输出。

你应用到数据的转换,使其能够安全地包含在SQL语句中,完全不同于你在HTML中应用的转换,完全不同于你在Javascript中应用的转换,完全不同于你在LDIF中应用的转换,完全不同于你应用到CSS中的转换,完全不同于你应用到Email....中的转换

务必验证输入——决定您是否应该接受它进行进一步处理,还是告诉用户它是不可接受的。但是不要对数据的表示进行任何更改,直到它离开PHP为止。

很久以前,有人试图发明一种适合所有人的机制来转义数据,我们最终使用了“magic_quotes”,它不能正确地转义所有输出目标的数据,导致不同的安装需要不同的代码才能工作。

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

像Twig或Latte这样的模板引擎默认有输出转义-如果你根据上下文(HTML或Javascript部分的网页)正确地转义了你的输出,你不必手动解决。

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

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

你可以在这里阅读更多关于它的内容-什么是软件框架?