fix: clamp session max age before KV write

This commit is contained in:
MarSeventh
2026-06-09 18:56:44 +08:00
parent 41fb51a631
commit 6e90b6bf3a
3 changed files with 42 additions and 4 deletions
+5 -2
View File
@@ -1,6 +1,7 @@
import { getDatabase } from '../../../utils/databaseAdapter.js';
import { hashPassword, isHashed } from '../../../utils/auth/passwordHash.js';
import { destroySessionsByAuthType } from '../../../utils/auth/sessionManager.js';
import { normalizeSessionMaxAgeDays } from '../../../utils/auth/sessionConfig.js';
export async function onRequest(context) {
// 安全设置相关,GET方法读取设置,POST方法保存设置
@@ -48,6 +49,8 @@ export async function onRequest(context) {
// 覆盖设置,apiTokens不在这里修改
settings.upload = newSettings.upload || settings.upload
settings.access = newSettings.access || settings.access
settings.access.userSessionMaxAge = normalizeSessionMaxAgeDays(settings.access.userSessionMaxAge)
settings.access.adminSessionMaxAge = normalizeSessionMaxAgeDays(settings.access.adminSessionMaxAge)
// 处理认证设置:空密码表示不修改,_clear 标记表示清除密码
let userPasswordChanged = false;
@@ -162,8 +165,8 @@ export async function getSecurityConfig(db, env) {
whiteListMode: kvAccess.whiteListMode ?? env.WhiteList_Mode === 'true',
// 新增会话安全策略字段
sessionSecure: kvAccess.sessionSecure ?? false,
userSessionMaxAge: kvAccess.userSessionMaxAge ?? 14,
adminSessionMaxAge: kvAccess.adminSessionMaxAge ?? 14,
userSessionMaxAge: normalizeSessionMaxAgeDays(kvAccess.userSessionMaxAge ?? 14),
adminSessionMaxAge: normalizeSessionMaxAgeDays(kvAccess.adminSessionMaxAge ?? 14),
}
settings.access = access
+33
View File
@@ -0,0 +1,33 @@
const DEFAULT_SESSION_MAX_AGE_DAYS = 14;
const MAX_SESSION_MAX_AGE_DAYS = 3650;
const SECONDS_PER_DAY = 86400;
const MAX_KV_EXPIRATION_TTL = 2147483647;
/**
* Normalize persisted session max age to an integer day count.
* Values outside the expected day range are treated as invalid so timestamp
* values such as Date.now() do not become long-lived sessions.
*/
export function normalizeSessionMaxAgeDays(value) {
const days = typeof value === 'string' && value.trim() !== ''
? Number(value)
: value;
if (!Number.isFinite(days)) {
return DEFAULT_SESSION_MAX_AGE_DAYS;
}
const normalizedDays = Math.trunc(days);
if (normalizedDays < 1 || normalizedDays > MAX_SESSION_MAX_AGE_DAYS) {
return DEFAULT_SESSION_MAX_AGE_DAYS;
}
return normalizedDays;
}
export function sessionMaxAgeDaysToTtl(days) {
const normalizedDays = normalizeSessionMaxAgeDays(days);
const ttl = normalizedDays * SECONDS_PER_DAY;
return Math.min(ttl, MAX_KV_EXPIRATION_TTL);
}
+4 -2
View File
@@ -7,6 +7,7 @@
import { generateSessionToken } from './passwordHash.js';
import { getDatabase } from '../databaseAdapter.js';
import { fetchSecurityConfig } from '../sysConfig.js';
import { normalizeSessionMaxAgeDays, sessionMaxAgeDaysToTtl } from './sessionConfig.js';
const SESSION_PREFIX = 'manage@session@';
@@ -28,10 +29,11 @@ export async function createSession(env, authType, username = '') {
const securityConfig = await fetchSecurityConfig(env);
const accessConfig = securityConfig.access || {};
const secure = accessConfig.sessionSecure ?? false;
const maxAgeDays = authType === 'admin'
const rawMaxAgeDays = authType === 'admin'
? (accessConfig.adminSessionMaxAge ?? 14)
: (accessConfig.userSessionMaxAge ?? 14);
const maxAge = maxAgeDays * 86400;
const maxAgeDays = normalizeSessionMaxAgeDays(rawMaxAgeDays);
const maxAge = sessionMaxAgeDaysToTtl(maxAgeDays);
const db = getDatabase(env);
const token = generateSessionToken();