我正在使用php,mysql和smarty,我放置用户可以放置注释等.我已经在插入SQL注入数据库之前转义了字符.我还需要做什么?
XSS主要是关于HTML转义(*).每当你获取一串纯文本并将其放入HTML页面时,无论该文本是来自数据库,还是直接来自用户输入,来自文件,还是来自其他任何地方,都需要将其转义.
最小的HTML转义是将所有&
符号转换为&
和所有<
符号<
.当您将某些内容放入属性值时,您还需要转义用于分隔属性的引号字符,通常"
是"
.总是逃避两个引号("
和单引号撇号'
)并没有什么坏处,有些人也逃避>
了>
,尽管这只是XHTML中一个角点案例所必需的.
任何优秀的面向Web的语言都应该为您提供一个功能.例如在PHP中它是htmlspecialchars()
:
Hello, !
在Smarty模板中,它是escape
修饰符:
Hello, {$name|escape:'html'}!
真的,因为HTML-escaping是你想要的95%的时间(想要允许包含原始HTML标记的情况相对较少),这应该是默认的.较新的模板语言已经了解到,使用HTML转义选择加入是一个巨大的错误,导致无限的XSS漏洞,因此默认情况下是HTML-escape.
你可以让Smarty的行为像这样通过更改默认修饰符来html
.(除非你真的知道自己在做什么,否则不要htmlall
按照他们的建议使用,否则它可能会搞砸你所有的非ASCII字符.)
无论你做什么,在处理或放入数据库之前,不要陷入输入HTML的HTML转义或"消毒"的常见PHP错误.这是执行输出阶段编码的错误位置,会给您带来各种问题.如果你想验证你的输入以确保它是特定应用程序所期望的,那么很好,但在这个阶段淘汰或逃避"特殊"字符是不合适的.
*:当(a)您实际上想要允许用户发布HTML时,会出现XSS的其他方面,在这种情况下,您必须将其简化为可接受的元素和属性,这是一个复杂的过程,通常由像HTML Purifier这样的库完成,即便如此,也有漏洞.替代的,更简单的标记方案可能会有所帮助.并且(b)当您允许用户上传文件时,这是非常难以保证的.