包含:登录失败锁定、90天密码有效期、30分钟会话超时、 强制改密、登录审计日志、屏幕水印、企业背景图、 备案信息固定底部、favicon、JS空集合保护、 会话过期体验优化(403 JSON)、display_errors 关闭、 固定 key 根治 Integrity check failed 等全部改动 注意:config.inc.php/.htaccess/.user.ini 含敏感信息, 通过 .gitignore 排除,勿推送到公开仓库。
57 lines
2.9 KiB
PHP
57 lines
2.9 KiB
PHP
<?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 时自动 POST(js/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))
|
||
{
|
||
// 等保修复 v2(2026-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);
|
||
}
|