对于大多数网站来说,转义所有用户输入就足够了。还要确保会话id不会出现在URL中,这样它们就不会从 Referer
链接到另一个网站。此外,如果你允许你的用户提交链接,确保没有 javascript:
允许协议链接;当用户单击链接时,它们将立即执行脚本。
对于大多数网站来说,转义所有用户输入就足够了。还要确保会话id不会出现在URL中,这样它们就不会从 Referer
链接到另一个网站。此外,如果你允许你的用户提交链接,确保没有 javascript:
允许协议链接;当用户单击链接时,它们将立即执行脚本。
有很多方法可以实现XSS(参见http://ha.ckers.org/xss.html),而且很难捕捉到。
我个人将此委托给我正在使用的当前框架(例如代码点燃器)。虽然不完美,但它可能比我手工制作的程序捕捉到的更多。
如果您担心XSS攻击,那么将输出字符串编码为HTML是解决方案。如果您记得将每个输出字符编码为HTML格式,那么就没有办法执行成功的XSS攻击。
阅读更多:净化用户数据:如何和在哪里做
转义输入并不是成功防止XSS的最好方法。输出也必须转义。如果你使用Smarty模板引擎,你可以使用 |escape:'htmlall'
修饰符将所有敏感字符转换为HTML实体(我使用own |e
修饰符,它是上述的别名)。
我的输入/输出安全方法是:
“Magic quotes”是对一些最糟糕的XSS缺陷的缓和补救,它通过逃避输入上的所有内容来工作,这是设计上的错误。唯一想要使用它的情况是,您绝对必须使用已知在XSS方面粗心编写的现有PHP应用程序。(在这种情况下,即使是“神奇的引用”,你也会遇到严重的麻烦。)在开发自己的应用程序时,应该禁用“神奇的引号”,而是遵循xss安全的实践。
XSS是一种跨站脚本漏洞,当应用程序在其[X]HTML、CSS、ECMAscript或其他浏览器解析输出中包含来自外部源(用户输入、从其他网站获取等)的字符串而没有适当转义,希望像<(在[X]HTML中)、单引号或双引号(ECMAscript)等特殊字符永远不会出现时,就会发生XSS。正确的解决方案是始终根据输出语言的规则转义字符串:在[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
这不是一个完整的答案,但希望足够帮助你开始。
就我个人而言,我会禁用magic_quotes。在PHP5+中,它是默认禁用的,最好编码时就像它根本不存在一样,因为它不会转义所有内容,它将从PHP6中删除。
接下来,根据你要过滤的用户数据的类型来决定下一步要做什么,例如,如果它只是文本,例如一个名字,那么 strip_tags(trim(stripslashes()));
它或使用正则表达式检查范围。
如果期望有一定范围的值,则创建一个有效值数组,并且只允许这些值通过(in_array($userData, array(...))
).
如果要检查数字,则使用is_numeric强制执行整数或强制转换为特定类型,这应该会防止人们试图发送字符串代替。
如果你有PHP5.2+,那么考虑一下filter(),并利用该扩展可以过滤各种数据类型,包括电子邮件地址。文档不是特别好,但正在改进。
如果你必须处理HTML,那么你应该考虑像PHP输入过滤器或HTML净化器。HTML Purifier也将验证HTML的一致性。我不确定输入过滤器是否还在开发中。两者都允许您定义一组可以使用的标记和允许的属性。
无论您决定做什么,一定要记住,永远不要相信来自用户(包括您自己!)的任何内容。
rikh写道:
我尽我所能总是调用htmlentities()的任何我输出的派生自用户输入。
请参阅Joel的文章《让代码看起来错误》以获得帮助