PHP论坛img BBCode链接校验:匹配指定路径后缀 过滤非法跳转链接
问题原因
- 正则语法错误:你在数字匹配段错误插入了
/^和$/,^和$是正则的全局起止定位符,不能放在路径中间使用,额外添加的/也不属于规则内容,会要求匹配路径中实际不存在的/^字符串,导致所有合法链接都无法命中白名单规则,全部触发后面的替换逻辑。 - 后缀匹配规则错误:使用
.*?匹配后缀会允许任意字符存在,依然没有封堵../路径跳转的绕过漏洞,也没有限制允许的文件扩展名。 - 没有做大小写兼容:用户上传的图片后缀可能存在大写(比如
PNG/JPEG),没有加忽略大小写修饰符会导致合法后缀被误拦截。
修复后的代码
'preg' => array( // 白名单规则,加i修饰符兼容大小写后缀 '#\[img:$uid\]http://www\.example\.com/images/\d+\.(jpg|jpeg|gif|png)\[/img:$uid\]#si' => $this->bbcode_tpl('img', $bbcode_id), '#\[img:$uid\]http://www\.example\.com/images/thumbs/\d+\.jpg\[/img:$uid\]#si' => $this->bbcode_tpl('img', $bbcode_id), '#\[img:$uid\]http://www\.example\.com/pictures/_f/f_\d+\.(jpg|jpeg|gif|png)\[/img:$uid\]#si' => $this->bbcode_tpl('img', $bbcode_id), '#\[img:$uid\]http://www\.example\.com/pictures/_t/t_\d+\.jpg\[/img:$uid\]#si' => $this->bbcode_tpl('img', $bbcode_id), // 其余全部替换 '#\[img:$uid\](.*?)\[/img:$uid\]#s' => str_replace('$2', 'External Image', $this->bbcode_tpl('url', $bbcode_id, true)), )
额外优化建议
如果要进一步提升安全性,可以在正则中限制数字部分的长度(比如你的示例是10位数字,可以把\d+改成\d{10}),避免异常长度的文件名绕过。另外也可以在后端获取到链接后先用realpath解析真实路径,二次校验是否在允许的目录范围内,双重保障避免正则漏判。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

