Files
人事系统开发 1ba6efd8ed MRBS 1.12.2 等保2.0二级整改完整提交
包含:登录失败锁定、90天密码有效期、30分钟会话超时、
强制改密、登录审计日志、屏幕水印、企业背景图、
备案信息固定底部、favicon、JS空集合保护、
会话过期体验优化(403 JSON)、display_errors 关闭、
固定 key 根治 Integrity check failed 等全部改动

注意:config.inc.php/.htaccess/.user.ini 含敏感信息,
通过 .gitignore 排除,勿推送到公开仓库。
2026-09-09 16:55:02 +08:00

57 lines
2.9 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace MRBS;
// An Ajax page to update the current page in the server. Called by the client when it switches URL
// on the fly.
require '../defaultincludes.inc';
// 等保整改(2026-09-09):会话过期 / 令牌失效时静默失败,不再渲染整页错误。
//
// 背景:原版在此调用 Form::checkToken(),其校验失败时会:
// 1) session()->logoffUser() —— 把当前(可能是另一个标签页里仍然有效的)会话直接登出;
// 2) Errors::fatalError() 渲染整页“会话已过期”错误页(print_simple_header)。
// 而 style.inc 输出的 CSS 均为相对路径(jquery/...、css/mrbs.css.php),在 /ajax/
// 子目录下渲染时会被浏览器解析成 /ajax/jquery/... 等,造成大批 404(控制台噪音)。
//
// 触发场景:本接口会被每个日历页面在 page_ready 时自动 POSTjs/index.js.php),
// 属于“通知型”调用。会话按等保要求收紧为空闲 30 分钟 / 绝对 12 小时后过期,或
// 用户跨标签页重新登录后,旧页面内嵌的 CSRF token 已与服务端会话不一致,原版
// 逻辑便会触发上述整页错误渲染 + 意外登出。
//
// 本接口仅用于在服务端记录“用户当前浏览页”($_SESSION['this_page'],供返回/后退
// 功能使用),不产生任何业务状态变更,也不返回任何会被客户端处理的内容;CSRF
// 令牌在这里失配没有任何可利用的安全后果(攻击者无法伪造令牌去写他人会话)。
// 因此改为:令牌缺失或不匹配时静默退出(空 200),不做登出、不渲染页面。
// 所有真实写操作(订房、改密、用户管理等)仍由各自的 handler 页面调用
// Form::checkToken() 严格校验,安全基线不变。
$token = get_form_var('csrf_token', 'string', null, INPUT_POST);
$stored_token = session()->get('csrf_token');
// 同步记录请求里的 page 字段(供前端跳回登录后用 returl 还原回原页面)
$page_hint = get_form_var('page', 'string', null, INPUT_POST);
if (!is_string($stored_token) || !is_string($token) || !hash_equals($stored_token, $token))
{
// 等保修复 v22026-09-09):返回 403 + JSON 信号,让前端 js/index.js.php
// 识别后 location.href='index.php?returl=...' 引导用户重新登录。
// 比 v1 静默空响应更友好:用户空闲超时回来不会被静默登出/卡死。
// 安全基线不变:本接口仍无业务状态变更;JSON 中只回显 page 字段(用户自己
// 刚浏览的相对 URL,不含敏感信息)。
http_response_code(403);
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'reason' => 'session_expired',
'returl' => is_string($page_hint) ? $page_hint : null,
]);
exit;
}
$page = get_form_var('page', 'string');
if (isset($page) && ($page !== ''))
{
session()->updatePage($page);
}