【发布时间】:2012-04-13 11:58:14
【问题描述】:
我最近在 phpbb2 的 bbcode.php 上编辑了一些正则表达式,我想知道它是否会带来安全问题(主要是从 href 注入脚本(如果可能的话))。
我只编辑了 [url]、[url=] 和我新创建的 [url=""] bbcode 标签。
他们的原始正则表达式(日期为 2008 年)不允许在 url 值中使用“无效”字符,例如括号或空格(某些 Wikipedia 页面和文件托管服务的 URL 需要这些字符),因此不是对根据其他人的建议,URL 的特殊字符,我只是编辑了正则表达式以允许协议中的字母数字字符,并且基本上是域/url 地址的其余部分中的任何字符。
phpbb2 的 bbencode_second_pass 函数中的新正则表达式($text = post's text):
// matches a [url]xxxx://www.phpbb.com[/url] code..
$patterns[] = "#\[url\]([\w]+?://.*?)\[/url\]#is";
$replacements[] = $bbcode_tpl['url1'];
// [url]www.phpbb.com[/url] code.. (no xxxx:// prefix).
$patterns[] = "#\[url\]((www|ftp)\..*?)\[/url\]#is";
$replacements[] = $bbcode_tpl['url2'];
// [url=xxxx://www.phpbb.com]phpBB[/url] code..
$patterns[] = "#\[url=([\w]+?://.*?)\]([^?\n\r\t].*?)\[/url\]#is";
$replacements[] = $bbcode_tpl['url3'];
// [url=www.phpbb.com]phpBB[/url] code.. (no xxxx:// prefix).
$patterns[] = "#\[url=((www|ftp)\..*?)\]([^?\n\r\t].*?)\[/url\]#is";
$replacements[] = $bbcode_tpl['url4'];
// [url="xxxx://www.phpbb.com"]phpBB[/url] code..
$patterns[] = "#\[url="([\w]+?://.*?)"\]([^?\n\r\t].*?)\[/url\]#is"; //closes on first "]
//$patterns[] = "#\[url="([\w]+?://.*?)"\](?![\w\n\s]*"\])([^?\n\r\t].*?)\[/url\]#is"; //closes on last "] //discarded, ambigous
$replacements[] = $bbcode_tpl['url3'];
// [url="www.phpbb.com"]phpBB[/url] code.. (no xxxx:// prefix).
$patterns[] = "#\[url="((www|ftp)\..*?)"\]([^?\n\r\t].*?)\[/url\]#is";
$replacements[] = $bbcode_tpl['url4'];
// [email]user@domain.tld[/email] code..
$patterns[] = "#\[email\]([a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+)\[/email\]#si";
$replacements[] = $bbcode_tpl['email'];
$text = preg_replace($patterns, $replacements, $text);
// Remove our padding from the string..
$text = substr($text, 1);
return $text;
还有未经编辑的 phpbb2 声明:
$bbcode_tpl['url1'] = str_replace('{URL}', '\\1', $bbcode_tpl['url']);
$bbcode_tpl['url1'] = str_replace('{DESCRIPTION}', '\\1', $bbcode_tpl['url1']);
$bbcode_tpl['url2'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']);
$bbcode_tpl['url2'] = str_replace('{DESCRIPTION}', '\\1', $bbcode_tpl['url2']);
$bbcode_tpl['url3'] = str_replace('{URL}', '\\1', $bbcode_tpl['url']);
$bbcode_tpl['url3'] = str_replace('{DESCRIPTION}', '\\2', $bbcode_tpl['url3']);
$bbcode_tpl['url4'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']);
$bbcode_tpl['url4'] = str_replace('{DESCRIPTION}', '\\3', $bbcode_tpl['url4']);
到目前为止,这在我的调试中工作得很好,现在我想问一下,通过允许将任何字符放置在 A 标签的 href 属性中,我是否会让我的用户或我自己受到任何黑客攻击?
说,我测试了 javascript URI hack (javascript:),它似乎在 Internet Explorer 上也不起作用,而且我不知道通过 A 标签的 href 属性注入脚本的任何方法,允许我的用户在 href标签?
请注意,我不考虑链接到恶意网站,我想知道黑客是否能够通过标签的 href 注入脚本/cookies/任何东西,而无需用户点击它!
现在让 href 属性运行任何东西而不点击其标签听起来有点多余,但无论如何,黑客有没有办法通过 href 属性在文档中注入恶意代码/javascript?
【问题讨论】:
-
空格和回车在 URL 中是非法的并且违反规范。空格字符应编码为
%20。如果您必须包含回车符/行尾,您可以根据需要使用%0A和/或%0D这样做 -
如果您指的是 RFC 规范,那么即使括号也是非法的,并且某些 Wikipedia 页面需要它们。我知道编码可能是一个很好的解决方案,但我不会要求我的最终用户知道如何对他们自己的 URL 进行编码,并且在 phpbb 中它与实现的内容没有太大区别:phpbb 允许用户用我的 mod 输入空格,但是当生成 HTML 时,所有非法字符都被正确编码 - 比如,
[url=www.a.com/a a]...[/url]变成了<a href="http://www.a.com/a%20a">...</a>。