在PHP站点中避免xss攻击的最佳实践是什么

时间:2020-03-05 18:55:40  来源:igfitidea点击:

我已配置PHP,以便打开魔术引号,并关闭全局寄存器。

我尽我所能一直对我从用户输入派生的任何输出调用htmlentities()。

我偶尔也会在数据库中查找xss附带的常见信息,例如...

<script

我还应该做些什么,以及如何确保自己一直想做的事情总是完成的。

解决方案

回答

对于大多数站点,转义所有用户输入就足够了。另外,请确保会话ID不会出现在URL中,以免它们从"引荐来源"链接到另一个站点的过程中被盗。另外,如果我们允许用户提交链接,请确保不允许使用" javascript:"协议链接;用户点击链接后,这些脚本将执行脚本。

回答

有很多方法可以执行XSS(请参阅http://ha.ckers.org/xss.html),并且很难掌握。

我个人将其委托给我正在使用的当前框架(例如Code Igniter)。虽然不完美,但它可能比我手工制作的例程所捕获的更多。

回答

如果我们担心XSS攻击,则将输出字符串编码为HTML是解决方案。如果我们记得将每个输出字符编码为HTML格式,则无法执行成功的XSS攻击。

阅读更多:
清理用户数据:如何以及在何处进行

回答

为了成功防止XSS,逃避输入并不是最好的选择。输出也必须转义。如果使用Smarty模板引擎,则可以使用| escape:'htmlall'修饰符将所有敏感字符转换为HTML实体(我使用自己的| e修饰符,这是上面的别名)。

我输入/输出安全性的方法是:

  • 存储未修改的用户输入(输入中没有转义HTML,仅通过PDO准备好的语句完成了DB感知的转义)
  • 在输出时进行转义,具体取决于我们使用的输出格式(例如HTML和JSON需要不同的转义规则)

回答

魔术引号是对某些最严重的XSS缺陷的治标之道,该缺陷可以通过转义输入中的所有内容而起作用,这在设计上是错误的。唯一要使用它的情况是,当我们绝对必须使用一个已知的关于XSS粗心编写的现有PHP应用程序时。 (在这种情况下,即使使用魔术引号,我们也会遇到严重的麻烦。)在开发自己的应用程序时,应禁用魔术引号,而应遵循XSS安全做法。

XSS是跨站点脚本漏洞,当应用程序在[X] HTML,CSS,ECMAscript或者其他浏览器解析的输出中包含来自外部源(用户输入,从其他网站等获取的字符串)的字符串而没有适当的转义,跳转时,就会发生这样,就不会出现小于号([X] HTML),单引号或者双引号(ECMAscript)之类的特殊字符。正确的解决方案是始终根据输出语言的规则对字符串进行转义:使用[X] HTML中的实体,ECMAscript中的反斜杠等。

因为很难跟踪不信任的内容和必须转义的内容,所以最好始终转义所有文本字符串,而不是像HTML这样带有标记的文本。某些编程环境通过引入几种不兼容的字符串类型使之更容易:字符串(普通文本),HTML字符串(HTML标记)等等。这样,就不可能将字符串直接隐式转换为HTML字符串,并且字符串成为HTML标记的唯一方法是将其传递给转义函数。

注册全局变量,尽管禁用它绝对是一个好主意,但处理的问题与XSS完全不同。

回答

使用现有的用户输入清理库来清除所有用户输入。除非我们付出很多努力,否则我们自己也无法实现。

回答

这是一个很好的问题。

首先,除了确保输入内容安全(例如放入数据库中)外,不要转义输入中的文本。这样做的原因是我们想保留输入的内容,以便可以不同的方式和位置在上下文中呈现它。在此处进行更改可能会损害我们以后的演示文稿。

当我们呈现数据时,请过滤掉不应该存在的内容。例如,如果没有理由在其中使用javascript,请进行搜索并将其删除。一种简单的方法是使用strip_tags函数,并仅显示我们允许的html标签。

接下来,使用我们拥有的内容,并传递htmlentities或者htmlspecialchars的思想,以将其中的内容更改为ASCII字符。根据上下文和我们想要获得的结果执行此操作。

我也建议关闭"魔术引号"。它已从PHP 6中删除,使用它被认为是不好的做法。有关详细信息,请访问http://us3.php.net/magic_quotes

有关更多详细信息,请访问http://ha.ckers.org/xss.html

这不是一个完整的答案,但希望足以入门。

回答

使我们使用HttpOnly的任何会话cookie(或者所有cookie)成为可能。在这种情况下,大多数浏览器都会从JavaScript隐藏cookie值。用户仍然可以手动复制cookie,但这有助于防止直接脚本访问。 StackOverflow在Beta期间出现此问题。

这不是解决方案,只是墙上的另一块砖

回答

就个人而言,我将禁用magic_quotes。在PHP5 +中,默认情况下将其禁用,并且最好将其编码为好像根本不存在,因为它无法逃逸所有内容,并且将从PHP6中删除。

接下来,根据我们要过滤的用户数据类型,我们将决定下一步要执行的操作,例如如果只是文字,例如名称,然后strip_tags(trim(stripslashes()));或者使用正则表达式检查范围。

如果期望某个值范围,则创建一个有效值数组,并仅允许这些值通过(in_array($ userData,array(...)))。

如果要检查数字,请使用is_numeric强制执行整数或者将其强制转换为特定类型,这应该可以防止人们尝试发送字符串。

如果我们有PHP5.2 +,则可以考虑使用filter()并利用该扩展名,该扩展名可以过滤包括电子邮件地址在内的各种数据类型。文档不是特别好,但是正在改进。

如果必须处理HTML,则应考虑使用类似PHP Input Filter或者HTML Purifier的工具。 HTML Purifier还将验证HTML的一致性。我不确定输入过滤器是否仍在开发中。两者都将允许我们定义一组可以使用的标签以及允许使用哪些属性。

无论我们做出什么决定,都请记住,永远不要相信任何来自用户(包括我们自己!)的PHP脚本。

回答

rikh Writes:
  
  
    I do my best to always call htmlentities() for anything I am outputing that is derived from user input.

有关此方面的帮助,请参见Joel的有关使代码看起来错误的文章。

回答

所有这些答案都是不错的选择,但是从根本上讲,XSS的解决方案是停止通过字符串操作生成HTML文档。

对于任何应用程序,过滤输入始终是一个好主意。

只要使用正确,使用htmlentities()和朋友转义输出就可以正常工作,但这在HTML上等同于通过将字符串与应该工作的mysql_real_escape_string($ var)连接来创建SQL查询,但是可以验证工作的工作很少,可以说,与使用参数化查询之类的方法相比。

长期的解决方案应该是应用程序内部构建页面,也许使用诸如DOM之类的标准接口,然后使用库(如libxml)来处理到XHTML / HTML / etc的序列化。当然,与流行和足够快的距离还有很长的路要走,但是与此同时,我们必须通过字符串操作来构建HTML文档,这本质上更具风险。

回答

  • 不信任用户输入
  • 转义所有自由文本输出
  • 不要使用magic_quotes;查看是否有特定于DBMS的变体,或者使用PDO
  • 考虑尽可能使用仅HTTP的cookie,以避免任何恶意脚本能够劫持会话

回答

我认为,在输入过程中,仅在输出时,不应逃避任何操作。由于(大多数时候)我们不能假设我们知道数据的去向。例如,如果我们有一个接收数据的表格,该表格后来出现在我们发送的电子邮件中,则需要进行不同的转义(否则恶意用户可能会重写电子邮件标题)。

换句话说,我们只能在数据"离开"应用程序的最后一刻转义:

  • 项目清单
  • 写入XML文件,转义为XML
  • 写入数据库,转义(针对该特定的DBMS)
  • 写电子邮件,转义电子邮件
  • 等等

简而言之:

  • 我们不知道数据要去哪里
  • 数据实际上可能会在一个以上的地方结束,需要使用不同的转义机制,但不能同时
  • 为错误的目标转义的数据确实不好。 (例如,收到一封主题为"转到汤米的酒吧"的电子邮件。)

如果我们在输入层对数据进行转义(或者需要再次对其进行转义,等等),则会出现Esp#3.

PS:我将不使用magic_quotes的建议列为第二,那是纯粹的邪恶!

回答

我发现使用此功能有助于消除很多可能的xss攻击:
http://www.codebelay.com/killxss.phps

回答

我发现最好的方法是使用一个类,该类允许我们绑定代码,因此我们不必担心手动转义数据。

回答

在不会引起错误警报的站点上实施全面的sql injection / xss注入预防非常困难。在CMS中,最终用户可能希望使用链接到另一个站点项目的" <脚本>"或者" <对象>"。

我建议让所有用户使用NoScript安装FireFox ;-)

回答

我依靠PHPTAL。

与Smarty和纯PHP不同,它默认情况下会转义所有输出。这是安全方面的一大胜利,因为如果我们忘记了某个地方的htmlspecialchars()或者| escape,则网站将不会受到威胁。

XSS是HTML特有的攻击,因此HTML输出是防止它的正确位置。我们不应该尝试对数据库中的数据进行预过滤,因为我们可能需要将数据输出到不接受HTML但有其自身风险的另一种介质。

回答

模板库。至少,这就是模板库应该做的。
为了防止XSS,应对所有输出进行编码。这不是主要应用程序/控制逻辑的任务,它应该仅由输出方法处理。

如果我们在代码中撒满htmlentities(),则总体设计是错误的。正如我们所建议的,我们可能会错过一两个景点。
这就是为什么唯一的解决方案是严格的html编码->当输出vars被写入html / xml流时。

不幸的是,大多数php模板库仅添加了自己的模板语法,而与输出编码,本地化,html验证或者其他重要内容无关。也许其他人知道适合php的模板库?

回答

我们至少应该验证进入数据库的所有数据。并尝试验证离开数据库的所有数据。

mysql_real_escape_string可以很好地防止SQL注入,但是XSS则比较棘手。
我们应该尽可能使用preg_match,stip_tags或者htmlentities!