【问题标题】:Regex and the "war" on XSS正则表达式和 XSS 上的“战争”
【发布时间】:2009-04-09 14:58:54
【问题描述】:

我一直对编写像论坛或博客这样的网络软件很感兴趣,这些东西需要有限的标记才能重写为 HTML。但是最近,我越来越多地注意到对于 PHP,尝试在谷歌上搜索“PHP BBCode parser -PEAR”并测试一些,你要么效率低下,要么代码很差,到处都是 XSS 漏洞。

以我之前提到的例子,那些糟糕的 BBCode 解析器,你将如何避免 XSS?我现在将使用您处理链接的典型正则表达式,您可以提及它的脆弱性以及如何避免它。

// Assume input has already been encoded by htmlspecialchars with ENT_QUOTES
$text = preg_replace('#\[url\](.*?)\[/url\]#i','<a href="\1">\1</a>', $text);
$text = preg_replace('#\[url=(.*?)\](.*?)\[/url\]#i','<a href="\1">\2</a>', $text);

处理图像标签几乎没有比这更安全的了。

所以我有几个具体问题,主要针对 PHP 实现。

  1. 在此示例中,仅使用 uri/url 验证表达式进行匹配是否更好?或者,最好使用(.*?) 和回调,然后确定输入是否是有效链接?正如上面显而易见的,javascript:alert('XSS!') 可以在上面的 URL 标记中工作,但如果完成 uri 匹配,则会失败。
  2. 回调中的 urlencode() 之类的函数呢,它们会是什么威慑或问题(就 URI 标准而言)?
  3. 编写全栈解析器会更安全吗?或者,开发和使用这样的东西所需的时间和处理能力对于每页处理多个不同条目的东西来说是否过于繁重?

我知道我的示例是众多示例之一,并且比某些示例更具体。但是,不要逃避提供自己的。 因此,我正在寻找在文本解析情况下 XSS 保护的原则和最佳实践以及一般建议。

【问题讨论】:

    标签: regex xss markup text-parsing bbcode


    【解决方案1】:

    测试一些,你要么得到一个低效的混乱,要么你得到带有 XSS 漏洞的糟糕代码

    该死的。我还没有遇到过不受 XSS 攻击的 bbcode 实现。

    '<a href="\1">\1</a>'
    

    不好:无法 HTML 转义 ‘

    在此示例中,仅使用 uri/url 验证表达式进行匹配是否更好?或者,最好使用 (.*?) 和回调,然后确定输入是否是有效链接?

    我会接受回调。无论如何,您都需要回调来进行 HTML 转义;仅通过简单的字符串替换是不可能安全的。在你做的时候把消毒剂放进去。

    回调中的 urlencode() 之类的函数呢

    几乎;实际上你需要 htmlspecialchars()。 urlencode() 是关于编码查询参数的,这不是你需要的。

    写一个全栈解析器会更安全吗?

    是的。

    bbcode 并不真正适合正则表达式解析,因为它是一种基于递归标记的语言(如 XML,正则表达式也无法解析)。许多 bbcode 漏洞是由嵌套和错误嵌套问题引起的。例如:

    [url]http://www.example.com/[i][/url]foo[/i]
    

    可能是这样的

    <a href="http://www.example.com/&lt;i>">foo</i>
    

    还有许多其他陷阱会在各种 bbcode 实现上生成损坏的代码(最多包括 XSS 漏洞)。

    我正在寻找原则和最佳实践

    如果您需要一种可以进行正则表达式的类似 bbcode 的语言,您需要:

    • 减少可以放入其他标签中的可能标签的数量。真的不可能支持任意嵌套
    • 使用特殊字符作为“”HTML 标记分隔符,以将它们与应该在文本中显示的真实尖括号区分开来。我使用 ASCII 控制代码(之前在用户输入阶段过滤掉了任何控制字符)。
    • 将在这些控制字符上处理的字符串拆分为这两个控制字符之间的内容,这样您就永远不会让 bbcode 跨度到达标签内部或标签边界之外。
    • 因为您不能让 bbcode 跨度通过标记边界从外向内工作,首先处理大块元素,然后向内处理链接,最后是粗体和斜体。
    • 为了理智,一次处理一个块。例如。如果您在双换行符上开始一个新的

      ,则 bbcode 标记不能跨越两个单独的块。

    仍然很难做到正确。一个合适的解析器更有可能是无懈可击的。

    【讨论】:

    • 嗯,我确实同意你所说的,但我在制作适当的解析器方面没有太多技能。知道 XML 式解析的任何体面教程吗?我发现很难找到一个不太复杂但仍处于必要技能水平的好人。
    • 如果您找不到满足您需求的第三方解析器库,您可以手动完成:首先 preg_split-with-PREG_SPLIT_DELIM_CAPTURE 在字符串上使用类似 '[[^]] +]' 来挑选标签,然后遍历列表,保留一堆打开的标签。
    • (列表中的偶数索引是文本,奇数索引是标签。通常文本会被 HTML 转义,如果你这样做可能会自动替换笑脸,但有些标签可能改变它。)
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 2018-10-02
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多