带BBcode的图像(php,preg_replace)。安全问题

时间:2011-06-02 11:27:10

标签: php security preg-replace csrf bbcode

Bbcode问题。这个:

$text = preg_replace("@\[img\](.*)\[\/img\]@si",
"<img src=\"$1\" border=\"0\" />", $text);

工作正常,但与此同时,这是一个很大的安全问题,例如:

[img]http://www.domain.com/delete-account/[/img]

[img]http://www.domain.com/logout/[/img]

如何控制这一点,以便只有以.jpg结尾的图像链接转换为html?

[img]http://www.domain.com/image.jpg[/img]

感谢。

2 个答案:

答案 0 :(得分:1)

根据the HTTP1.1 standard,使用GET(用于获取图像的方法)请求网址不应导致任何操作,例如注销。因此,您不需要限制最后带有.jpg的网址,而且一般来说,这是一个坏主意,因为还有其他图像格式,并且URL通常与其内容类型无关。

更重要的是,如果请求URL 更改服务器vulnerable.net的状态,则无论如何都可以通过设置自定义服务器来利用此Cross Site Request Forgery Vulnerability。 -redirects http://evil.com/img.jpghttp://vulnerable.net/logout

仅供参考,如果您真的只想替换以.jpg结尾的网址,您只需将其插入群组中即可:

$text = preg_replace("@\[img\](.*\.jpg)\[\/img\]@si",
                     "<img src=\"$1\" border=\"0\" />", $text);

但这不是一种安全机制,如果浏览器(或积极的缓存代理,或病毒扫描程序或......)预取URL,则会失败。 GET次请求不应导致任何操作。

答案 1 :(得分:0)

考虑这个问题的一种方法是在服务器端检查GEt和POST请求是不相等的。

POST请求可以更改服务器端的数据, GET请求更改任何内容。这是HTTP协议。 IMG标记始终是GET请求。并且浏览器可以毫无风险地执行此GET请求,因此问题是在服务器端,每个可以更改alter data(数据库,会话等)的操作都必须检查请求是否为POST。例如,您的/ post或/ delete-account网址应返回 403 或200代码,但需要表单页面,要求POST确认。如果你的应用程序出错了,那么你不仅会遇到更改IMG标签的问题,而且可能会遇到“html页面调速器”,这些问题会导致预加载GET参考,甚至是机器人。

如果您能找到this excellent book的副本,您可能会发现一些高级图片链接问题和过滤技巧。例如,外国网站上的链接有时会成为问题。但这是一个比以方便的方式处理GET和POST请求更复杂的问题。