How do I HTML Encode all the output in a web application?我想防止Web应用程序中的XSS攻击。 我发现HTML编码输出可以真正防止XSS攻击。 现在的问题是,如何对应用程序中的每个输出进行HTML编码? 我有办法自动化吗? 我感谢JSP,ASP.net和PHP的答案。 您不应该做的一件事就是对输入数据进行过滤。人们经常建议这样做,因为这是最简单的解决方案,但会带来问题。 输入数据除了可以输出为HTML之外,还可以发送到多个地方。例如,它可能存储在数据库中。筛选发送到数据库的数据的规则与筛选HTML输出的规则非常不同。如果对输入中的所有内容进行HTML编码,则最终将在数据库中使用HTML。 (这也是为什么PHP的"魔术引号"功能不是一个好主意的原因。) 您无法预期输入数据将行进的所有地点。安全的方法是在将数据发送到某处之前准备数据。如果要将其发送到数据库,请转义单引号。如果要输出HTML,请转义HTML实体。并将其发送到某个地方后,如果仍然需要处理数据,请使用原始的未转义版本。 这是更多的工作,但是您可以通过使用模板引擎或库来减少它。 您不想对所有HTML进行编码,而只想对输出的所有用户输入进行HTML编码。 对于PHP:htmlentities和htmlspecialchars 对于JSP,您也可以使用c:out标记来吃蛋糕,默认情况下,该标记会转义XML。这意味着您可以将属性绑定为原始元素:
当绑定到字符串时,someName.someProperty将包含XML输入,但是当输出到页面时,它将自动转义以提供XML实体。这对于页面验证链接特别有用。 我个人的喜好是对来自数据库,业务层或用户的任何内容进行认真编码。
在ASP.Net中,这是通过使用 对任何内容进行编码的原因是,即使您可能认为是布尔值或数字的属性也可能包含恶意代码(例如,复选框值(如果操作不当)可能会返回为字符串。如果您之前未对其进行编码,将输出发送给用户,那么您就有一个漏洞)。 您可以将echo / print等包装在您自己的方法中,然后使用它们对输出进行转义。即代替
采用
您甚至可以使用第二个参数,在需要时关闭转义。 在一个项目中,我们的输出函数具有调试模式,该模式使通过我们方法的所有输出文本均不可见。然后我们知道屏幕上剩下的所有内容都无法逃脱!跟踪那些顽皮的未转义位非常有用:) 我过去用来转义所有用户输入的一种好方法是编写一个修饰符,以便将所有传递给模板的变量转义。除了附加了| unscape的那些之外。这样,您就只允许HTML访问您显式授予的元素。 我没有那个修饰符了。但可以在这里找到相同的版本: http://www.madcat.nl/martijn/archives/16-Using-smarty-to-prevent-HTML-injection..html 在新的Django 1.0版本中,它的工作方式与jay完全相同:)
OWASP有一个不错的API,可以对HTML输出进行编码,既可以用作HTML文本(例如段落或
该项目(PHP版本)托管在http://code.google.com/p/owasp-esapi-php/下,并且还适用于其他一些语言,例如。净。 请记住,您应该对所有内容(不仅是用户输入)进行编码,并应尽可能地进行编码(不是存储在DB中,而是输出HTTP响应时)。 到目前为止,输出编码是最好的防御方法。验证输入的原因很多,但并非100%防御。如果数据库通过攻击(即ASPROX)被XSS感染,错误或恶意输入验证则不执行任何操作。输出编码仍将起作用。 乔尔(Joel)撰写了一篇有关软件的好文章(使错误的代码看起来不正确,我想,我在手机上,否则我会给您提供URL)涵盖了正确使用匈牙利表示法。简短的版本是这样的:
基本上为变量加上前缀,例如" us"表示不安全的字符串," ds"表示数据库安全," hs"表示HTML安全。您只想在实际需要的地方进行编码和解码,而不是所有内容。但是通过使用它们前缀可以推断出有用的含义,即查看代码后,如果出现问题,您会很快发现。无论如何,您将需要不同的编码/解码功能。 真正保护自己免受此类攻击的唯一方法是严格筛选您接受的所有输入,特别是(尽管不是唯一地)来自应用程序公共区域的所有输入。我建议您看一下Daniel Morris的PHP过滤类(完整的解决方案)以及Zend_Filter包(可用于构建自己的过滤器的类的集合)。 在Web开发方面,PHP是我选择的语言,因此对我的回答中的偏见表示歉意。 基兰 如果您确实对每个输出进行HTML编码,则用户将看到的纯文本,而不是正常运行的Web应用程序。 编辑:如果您对每个输入进行HTML编码,则在接受包含<等的外部密码时会遇到问题。 |