正则表达式和“战争” 跨站脚本攻击
我一直对编写网络软件(例如论坛或博客)感兴趣,这些软件需要有限的标记才能重写为 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 实现的。
- 在此示例中,仅使用 uri/url 验证表达式进行匹配是否是更好的做法? 或者,最好使用
(.*?)
和回调,然后确定输入是否是有效链接? 从上面可以明显看出,javascript:alert('XSS!')
可以在上述 URL 标记中工作,但如果完成 uri 匹配,则会失败。 - 回调中像
urlencode()
这样的函数怎么样,它们会产生任何威慑或问题吗(就 URI 标准而言)? - 编写一个全栈解析器会更安全吗? 或者,开发和使用这样的东西所需的时间和处理能力对于每页处理多个不同条目的东西来说是否太重了?
我知道我的例子只是众多例子之一,而且比一些例子更具体。 但是,不要回避提供自己的。 因此,我正在寻找文本解析情况下 XSS 保护的原则和最佳实践以及一般建议。
I've always been interested in writing web software like forums or blogs, things which take a limited markup to rewrite into HTML. But lately, I've noticed more and more that for PHP, try googling "PHP BBCode parser -PEAR" and test a few out, you either get an inefficient mess, or you get poor code with XSS holes here and there.
Taking my previously mentioned example, of the poor BBCode parsers out there, how would you avoid XSS? I'll now take your typical regular expression for handling a link, and you can mention how vulnerable it is and how to avoid it.
// 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);
Handling image tags are hardly more secure than this.
So I have several specific questions, mostly specific to PHP implementations.
- Is it better practice, in this example, to only match using a uri/url validation expression? Or, is it better to use
(.*?)
and a callback, then ascertain whether or not the input is a valid link? As would be obvious above, thejavascript:alert('XSS!')
would work in the above URL tags, but would fail if the uri-matching was done. - What about functions like
urlencode()
within a callback, would they be any deterrence or problem (as far as URI standards go)? - Would it be safer to write a full-stack parser? Or, is the time and processing power needed to develop and use such a thing too weighty for something handling several different entries per page?
I know my example is one of many, and is more specific than some. However, don't shirk from providing your own. So, I'm looking for principles and best practices, and general recommendations for XSS-protection in a text-parsing situation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哎呀,是的。 我还没有遇到过不存在 XSS 漏洞的 bbcode 实现。
不好:无法对 '<'、'&' 进行 HTML 转义 和 '"' 字符。
我会接受回电。 无论如何,您都需要回调来执行 HTML 转义; 仅通过简单的字符串替换不可能保证安全。 当你这样做的时候,把消毒剂放进去。
? 实际上你需要 htmlspecialchars()。 urlencode() 是关于对查询参数进行编码的,这不是您在这里需要的。
是的。
bbcode 并不真正适合正则表达式解析,因为它是一种基于递归标记的语言(如 XML,正则表达式也无法解析)。 许多 bbcode 漏洞是由嵌套和错误嵌套问题引起的。 例如:
可能会出现类似
在各种 bbcode 实现上生成损坏代码(最多包括 XSS 漏洞)的许多其他陷阱。
如果您需要一种可以进行正则表达式的类似 bbcode 的语言,您需要:
在双换行符上,任何 bbcode 标签都不能跨越两个单独的块。
想要做到正确仍然非常困难。 一个合适的解析器更有可能是无懈可击的。
Hell yeah. I've not met a bbcode implementation yet that wasn't XSS-vulnerable.
No good: fails to HTML-escape ‘<’, ‘&’ and ‘"’ characters.
I would take the callback. You need the callback anyway to do the HTML-escaping; it's not possible to be secure with only simple string replacement. Drop the sanitisation in whilst you're doing it.
Nearly; actually you need htmlspecialchars(). urlencode() is about encoding query parameters, which isn't what you need here.
Yes.
bbcode is not really amenable to regex parsing, because it's a recursive tag-based language (like XML, which regex also cannot parse). Many bbcode holes are caused by nesting and misnesting problems. For example:
Could come out as something like
there are many other traps that generate broken code (up to an including XSS holes) on various bbcode implementations.
If you need a bbcode-like language that you can regex, you need to:
It's still damned hard to get right. A proper parser is much more likely to be watertight.