fix: harden cloud storage security

This commit is contained in:
237899745
2026-06-13 18:45:12 +08:00
parent 7943b04ee2
commit bb6ad01018
28 changed files with 2229 additions and 996 deletions

View File

@@ -1,10 +1,27 @@
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const { UserDB, DeviceSessionDB } = require('./database');
const { UserDB, DeviceSessionDB, SystemLogDB } = require('./database');
const { decryptSecret } = require('./utils/encryption');
const DEFAULT_LOCAL_STORAGE_QUOTA_BYTES = 1024 * 1024 * 1024; // 1GB
const DEFAULT_OSS_STORAGE_QUOTA_BYTES = 1024 * 1024 * 1024; // 1GB
function normalizeDownloadTrafficQuotaForAuth(rawQuota) {
if (rawQuota === null || rawQuota === undefined || rawQuota === '') {
return -1; // 未设置时默认不限流量
}
const parsedQuota = Number(rawQuota);
if (!Number.isFinite(parsedQuota)) {
return -1;
}
if (parsedQuota < 0) {
return -1; // -1 表示不限流量
}
return Math.max(0, Math.floor(parsedQuota)); // 0 表示禁止下载
}
// JWT密钥必须在环境变量中设置
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production';
// Refresh Token密钥使用不同的密钥
@@ -17,7 +34,8 @@ const REFRESH_TOKEN_EXPIRES = '7d'; // Refresh token 7天
// 安全检查验证JWT密钥配置
const DEFAULT_SECRETS = [
'your-secret-key-change-in-production',
'your-secret-key-change-in-production-PLEASE-CHANGE-THIS'
'your-secret-key-change-in-production-PLEASE-CHANGE-THIS',
'your-secret-key-PLEASE-CHANGE-THIS-IN-PRODUCTION'
];
// 安全修复:增强 JWT_SECRET 验证逻辑
@@ -234,10 +252,7 @@ function authMiddleware(req, res, next) {
const effectiveOssQuota = Number.isFinite(rawOssQuota) && rawOssQuota > 0
? rawOssQuota
: DEFAULT_OSS_STORAGE_QUOTA_BYTES;
const rawDownloadTrafficQuota = Number(user.download_traffic_quota);
const effectiveDownloadTrafficQuota = Number.isFinite(rawDownloadTrafficQuota) && rawDownloadTrafficQuota > 0
? Math.floor(rawDownloadTrafficQuota)
: 0; // 0 表示不限流量
const effectiveDownloadTrafficQuota = normalizeDownloadTrafficQuotaForAuth(user.download_traffic_quota);
const rawDownloadTrafficUsed = Number(user.download_traffic_used);
const normalizedDownloadTrafficUsed = Number.isFinite(rawDownloadTrafficUsed) && rawDownloadTrafficUsed > 0
? Math.floor(rawDownloadTrafficUsed)
@@ -257,8 +272,6 @@ function authMiddleware(req, res, next) {
oss_provider: user.oss_provider,
oss_region: user.oss_region,
oss_access_key_id: user.oss_access_key_id,
// 安全修复:解密 OSS Access Key Secret如果存在
oss_access_key_secret: user.oss_access_key_secret ? decryptSecret(user.oss_access_key_secret) : null,
oss_bucket: user.oss_bucket,
oss_endpoint: user.oss_endpoint,
// 存储相关字段
@@ -276,6 +289,12 @@ function authMiddleware(req, res, next) {
// 主题偏好
theme_preference: user.theme_preference || null
};
Object.defineProperty(req.user, 'oss_access_key_secret', {
value: user.oss_access_key_secret ? decryptSecret(user.oss_access_key_secret) : null,
enumerable: false,
configurable: false,
writable: false
});
req.authSessionId = sessionId || null;
req.authTokenJti = typeof decoded.jti === 'string' ? decoded.jti : null;
@@ -321,14 +340,21 @@ function adminMiddleware(req, res, next) {
* );
*/
function requirePasswordConfirmation(req, res, next) {
const { password } = req.body;
const password = String(
req.body?.current_password ||
req.body?.admin_password ||
req.body?.password_confirmation ||
req.body?.password ||
''
);
// 检查是否提供了密码
if (!password) {
return res.status(400).json({
success: false,
message: '执行此操作需要验证密码',
require_password: true
require_password: true,
requirePasswordConfirmation: true
});
}
@@ -355,7 +381,6 @@ function requirePasswordConfirmation(req, res, next) {
if (!isPasswordValid) {
// 记录安全日志:密码验证失败
SystemLogDB = require('./database').SystemLogDB;
SystemLogDB.log({
level: SystemLogDB.LEVELS.WARN,
category: SystemLogDB.CATEGORIES.SECURITY,