问题:Cookie 缺少 HttpOnly/Secure/SameSite 安全属性
此文章为XIUNOX版本重构审计时发现问题,分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 用户登录态 Cookie bbs_token 通过 setcookie() 设置时,未指定 HttpOnly、Secure、SameSite 三个安全属性中的任何一个。这意味着:
- 无 HttpOnly:JavaScript 可通过
document.cookie 读取 bbs_token,配合任意 XSS 即可窃取用户登录态。
- 无 Secure:Cookie 在 HTTP 明文连接下也会被发送,中间人可嗅探窃取。
- 无 SameSite:浏览器默认不拦截跨站请求携带 Cookie,使后台 CSRF(见独立审计文件)可直接生效。
后台 Cookie bbs_admin_token 设置了 HttpOnly(第 7 参数为 TRUE),但仍未设置 Secure 和 SameSite,CSRF 与中间人嗅探风险依旧。
源码证据
证据 1:用户登录态 Cookie bbs_token 无任何安全属性 文件:xiunobbs_4.0.4/model/user.func.php 行 332-346
function user_token_set($uid) {
global $time, $conf;
if(empty($uid)) return;
$token = user_token_gen($uid);
setcookie('bbs_token', $token, $time + 8640000, $conf['cookie_path']);
}
function user_token_clear() {
global $time, $conf;
setcookie('bbs_token', '', $time - 8640000, $conf['cookie_path']);
}
第 336 行 setcookie('bbs_token', $token, $time + 8640000, $conf['cookie_path']); 仅传 4 个参数(name/value/expire/path),第 5 参数 domain 为空,第 6 参数 secure 为 FALSE(默认),第 7 参数 httponly 为 FALSE(默认)。SameSite 未设置(PHP 7.3+ 支持的关联数组形式未使用)。bbs_token 有效期长达 8640000 秒(约 100 天),泄露窗口极长。
证据 2:后台 Cookie bbs_admin_token 设了 HttpOnly 但无 Secure/SameSite 文件:xiunobbs_4.0.4/admin/admin.func.php 行 47-69
function admin_token_set() {
global $longip, $time, $useragent, $conf;
$useragent_md5 = md5($useragent);
$key = md5((XN_ADMIN_BIND_IP ? $longip : '').$useragent_md5.xn_key());
$admin_token = param('bbs_admin_token');
$s = "$longip $time";
$admin_token = xn_encrypt($s, $key);
setcookie('bbs_admin_token', $admin_token, $time + 3600, '', '', 0, TRUE);
}
function admin_token_clean() {
global $time;
setcookie('bbs_admin_token', '', $time - 86400, '', '', 0, TRUE);
}
第 59 行 setcookie('bbs_admin_token', $admin_token, $time + 3600, '', '', 0, TRUE); 第 6 参数 secure=0(FALSE),第 7 参数 httponly=TRUE。HttpOnly 已开启(防 XSS 读取),但 Secure=0 导致 HTTP 连接下可被嗅探,SameSite 未设置导致 CSRF 不受浏览器默认拦截。第 24、34、66 行清理 Cookie 时同样 secure=0。
证据 3:session Cookie 同样无安全属性(PHP 默认) Xiuno 使用 sess_start() 启动 session,未在 session_set_cookie_params 中设置安全属性,PHP 默认 session.cookie_httponly=0、session.cookie_secure=0、session.cookie_samesite=,session ID 同样可被 XSS 读取与 CSRF 利用。
风险等级与结论
风险等级:高危
结论:
bbs_token(用户登录态,有效期约 100 天)完全无 HttpOnly/Secure/SameSite,任意 XSS 即可窃取,HTTP 下可被嗅探,跨站请求可携带。
bbs_admin_token(后台登录态)虽设 HttpOnly,但无 Secure/SameSite,中间人嗅探与 CSRF 仍可生效,与后台无 CSRF Token 漏洞叠加形成完整 CSRF 攻击链。
- session Cookie 沿用 PHP 默认不安全配置。
- 修复建议:所有
setcookie 调用补齐 secure=TRUE(强制 HTTPS)、httponly=TRUE、samesite='Lax' 或 'Strict';通过 session_set_cookie_params 或 php.ini 设置 session.cookie_secure=1、session.cookie_httponly=1、session.cookie_samesite=Lax;对已签发的长效 bbs_token(100 天)缩短有效期或改为滑动过期。