Xiuno BBS 审计之问题09:登录回跳 referer 未严格校验,存在开放重定向风险
贰先生 4小时前

问题:登录回跳 referer 未严格校验,存在开放重定向风险

此文章为XIUNOX版本重构审计时发现问题,分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。

现象

Xiuno BBS 4.0.4 的 user_http_referer() 函数用于登录后回跳,它优先从 param('referer')(GET/POST 参数)获取回跳地址,仅在为空时才回退到 HTTP_REFERER。虽然函数对回跳地址做了正则校验(要求 ^[\w\/]*$  ^\??[\w\-/]+\.htm$),但该校验:

  1. 允许任意以字母数字下划线开头的相对路径,攻击者可构造 //evil.com/path 形式(双斜杠开头)绕过同站假设,浏览器会将其解析为协议相对 URL 跳转到外部域名
  2. 正则 ^[\w\/]*$ 允许纯 / 与字母组合,配合 http_location() 直接 header('Location:'.$url) 输出,无 host 白名单

http_location() 函数本身对传入 URL 完全不校验,任意路由调用它都可被用于重定向。

源码证据

文件:xiunobbs_4.0.4/route/user.php 行 405-423(user_http_referer 函数)

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 无校验)

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 白名单,业务代码任意调用即形成开放重定向

修复建议:

  1. 修复 $referer2 未定义变量 bug
  2. 校验回跳 URL 必须以 / 开头且不以 // 开头(防协议相对 URL)
  3. 解析 URL 后校验 host 必须等于当前站点 host
  4. http_location 增加 host 白名单参数,拒绝外部域名
最新回复 (0)
全部楼主
返回