问题:登录回跳 referer 未严格校验,存在开放重定向风险
此文章为XIUNOX版本重构审计时发现问题,分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 的 user_http_referer() 函数用于登录后回跳,它优先从 param('referer')(GET/POST 参数)获取回跳地址,仅在为空时才回退到 HTTP_REFERER。虽然函数对回跳地址做了正则校验(要求 ^[\w\/]*$ 或 ^\??[\w\-/]+\.htm$),但该校验:
- 允许任意以字母数字下划线开头的相对路径,攻击者可构造
//evil.com/path形式(双斜杠开头)绕过同站假设,浏览器会将其解析为协议相对 URL 跳转到外部域名 - 正则
^[\w\/]*$允许纯/与字母组合,配合http_location()直接header('Location:'.$url)输出,无 host 白名单
http_location() 函数本身对传入 URL 完全不校验,任意路由调用它都可被用于重定向。
源码证据
文件:xiunobbs_4.0.4/route/user.php 行 405-423(user_http_referer 函数)
php
function user_http_referer() {
// hook user_http_referer_start.php
$referer = param('referer'); // 优先从参数获取 | GET is priority
empty($referer) AND $referer = array_value($_SERVER, 'HTTP_REFERER', '');
$referer = str_replace(array('\"', '"', '<', '>', ' ', '*', "\t", "\r", "\n"), '', $referer); // 干掉特殊字符 strip special chars
// hook user_http_referer_check_start.php
if(
!preg_match('#^(http|https)://[\w\-=/\.]+/[\w\-=.%\#?]*$#is', $referer)
&& !preg_match('#^\??[\w\-/]+\.htm$#', $referer2)
|| strpos($referer, 'user-login.htm') !== FALSE
|| strpos($referer, 'user-logout.htm') !== FALSE
|| strpos($referer, 'user-create.htm') !== FALSE
|| strpos($referer, 'user-setpw.htm') !== FALSE
|| strpos($referer, 'user-resetpw_complete.htm') !== FALSE
) {
$referer = './';
}
// hook user_http_referer_end.php
return $referer;
}
注意:第二个正则分支引用了未定义变量 $referer2(应为 $referer),导致该分支永远不匹配,校验逻辑存在 bug。
文件:xiunobbs_4.0.4/xiunophp/misc.func.php 行 1363-1366(http_location 无校验)
php
function http_location($url) {
header('Location:'.$url);
exit;
}
调用点 route/user.php 行 60、116:登录成功后 message(0, jump(..., $referer, 1)),jump 最终通过 http_location 输出 Location 头。
风险等级与结论
中危
危害后果:
- 钓鱼攻击:攻击者构造
user-login.htm?referer=//evil.com/phishing链接诱骗用户登录,登录成功后跳转到钓鱼站点窃取二次凭据 - OAuth/SSO 回调劫持:若站点接入第三方登录,回跳地址可控可导致授权码被劫持
- 校验函数引用未定义变量
$referer2,第二正则分支永远失效,部分本应被拒的 URL 漏过 http_location无任何 host 白名单,业务代码任意调用即形成开放重定向
修复建议:
- 修复
$referer2未定义变量 bug - 校验回跳 URL 必须以
/开头且不以//开头(防协议相对 URL) - 解析 URL 后校验 host 必须等于当前站点 host
http_location增加 host 白名单参数,拒绝外部域名