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

我配置了PHP,使魔术引号是打开的和寄存器全局是关闭的。

我尽我所能总是调用htmlentities()的任何我输出的派生自用户输入。

我也偶尔搜索我的数据库中常用的东西在xss附件,如…

<script

我还应该做什么?我怎样才能确保我努力做的事情总是被完成。

请先 登录 后评论

10 个回答

Konrad Rudolph

对于大多数网站来说,转义所有用户输入就足够了。还要确保会话id不会出现在URL中,这样它们就不会从 Referer 链接到另一个网站。此外,如果你允许你的用户提交链接,确保没有 javascript: 允许协议链接;当用户单击链接时,它们将立即执行脚本。

请先 登录 后评论
Christian Studer

有很多方法可以实现XSS(参见http://ha.ckers.org/xss.html),而且很难捕捉到。

我个人将此委托给我正在使用的当前框架(例如代码点燃器)。虽然不完美,但它可能比我手工制作的程序捕捉到的更多。

请先 登录 后评论
Niyaz

如果您担心XSS攻击,那么将输出字符串编码为HTML是解决方案。如果您记得将每个输出字符编码为HTML格式,那么就没有办法执行成功的XSS攻击。

阅读更多:净化用户数据:如何和在哪里做

请先 登录 后评论
Michał Rudnicki

转义输入并不是成功防止XSS的最好方法。输出也必须转义。如果你使用Smarty模板引擎,你可以使用 |escape:'htmlall' 修饰符将所有敏感字符转换为HTML实体(我使用own |e 修饰符,它是上述的别名)。

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

  • 存储未修改的用户输入(输入时没有HTML转义,只有通过PDO预处理语句实现的db感知转义)
  • 根据你使用的输出格式(例如HTML和JSON需要不同的转义规则)
请先 登录 后评论
Alexey Feldgendler

“Magic quotes”是对一些最糟糕的XSS缺陷的缓和补救,它通过逃避输入上的所有内容来工作,这是设计上的错误。唯一想要使用它的情况是,您绝对必须使用已知在XSS方面粗心编写的现有PHP应用程序。(在这种情况下,即使是“神奇的引用”,你也会遇到严重的麻烦。)在开发自己的应用程序时,应该禁用“神奇的引号”,而是遵循xss安全的实践。

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

因为很难跟踪不可信的内容和必须转义的内容,所以总是转义所有“文本字符串”(而不是像HTML这样的语言中的“带有标记的文本”)的内容是个好主意。一些编程环境通过引入几种不兼容的字符串类型使其更容易:“字符串”(普通文本)、“HTML字符串”(HTML标记)等等。这样,从“字符串”到“HTML字符串”的直接隐式转换将是不可能的,字符串成为HTML标记的唯一方法是通过转义函数传递它。

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

请先 登录 后评论
dbr

使用现有的用户输入消毒库来清理所有用户输入。除非你投入大量的努力,否则你自己执行它永远不会有很好的效果。

请先 登录 后评论
Matt Farina

这是个好问题。

首先,不要对输入的文本进行转义,除非是为了使其能够安全地存储(比如放入数据库中)。这样做的原因是,您希望保留输入的内容,以便能够以不同的方式和地点上下文地呈现它。在这里进行更改可能会影响您稍后的演示。

在展示数据时,过滤掉不应该出现的内容。例如,如果没有javascript存在的理由,搜索并删除它。一种简单的方法是使用strip_tags函数,只显示允许的html标记。

接下来,将您拥有的内容传递给htmlentities或htmlspecialchars,以将那里的内容更改为ascii字符。根据上下文和你想要得到什么来做这件事。

我还建议关掉“魔力语录”。它已经从PHP 6中删除了,使用它被认为是不好的做法。在http://us3.php.net/magic_quotes上的细节

欲了解更多详情,请访问http://ha.ckers.org/xss.html

这不是一个完整的答案,但希望足够帮助你开始。

请先 登录 后评论
basszero

使您使用HttpOnly的任何会话cookie(或所有cookie)。在这种情况下,大多数浏览器会对JavaScript隐藏cookie值。用户仍然可以手动复制cookie,但这有助于防止直接访问脚本。StackOverflow在beta测试期间就有这个问题。

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

请先 登录 后评论
Community

就我个人而言,我会禁用magic_quotes。在PHP5+中,它是默认禁用的,最好编码时就像它根本不存在一样,因为它不会转义所有内容,它将从PHP6中删除。

接下来,根据你要过滤的用户数据的类型来决定下一步要做什么,例如,如果它只是文本,例如一个名字,那么 strip_tags(trim(stripslashes())); 它或使用正则表达式检查范围。

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

如果要检查数字,则使用is_numeric强制执行整数或强制转换为特定类型,这应该会防止人们试图发送字符串代替。

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

如果你必须处理HTML,那么你应该考虑像PHP输入过滤器HTML净化器。HTML Purifier也将验证HTML的一致性。我不确定输入过滤器是否还在开发中。两者都允许您定义一组可以使用的标记和允许的属性。

无论您决定做什么,一定要记住,永远不要相信来自用户(包括您自己!)的任何内容。

请先 登录 后评论
Mason

rikh写道:

我尽我所能总是调用htmlentities()的任何我输出的派生自用户输入。

请参阅Joel的文章《让代码看起来错误》以获得帮助

请先 登录 后评论