🔒 安全加固:修复多个中高危漏洞
修复内容: 1. Host Header 注入 - 添加 PUBLIC_BASE_URL 和 ALLOWED_HOSTS 白名单 2. API密钥暴力破解 - 添加速率限制(5次/小时,封锁24小时) 3. 路径遍历漏洞 - 增强路径验证,防止空字节注入和目录遍历 4. 令牌安全 - 密码重置和邮箱验证令牌使用SHA256哈希存储 5. 文件上传安全 - 阻止PHP/JSP/ASP等可执行脚本上传 6. IDOR防护 - 增强权限验证和安全日志 7. XSS防护 - 增强输入过滤,阻止javascript:等危险协议 8. 日志脱敏 - 移除验证码等敏感信息的日志输出 9. CSRF增强 - HTTPS环境使用strict模式Cookie 10. 邮箱枚举防护 - 密码重置统一返回消息 11. 速率限制 - 文件列表(60次/分)和上传(100次/小时) 配置说明: - PUBLIC_BASE_URL: 必须配置,用于生成安全的邮件链接 - ALLOWED_HOSTS: 可选,Host头白名单 - COOKIE_SECURE=true: 生产环境必须开启 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -231,27 +231,55 @@ class LocalStorageClient {
|
||||
|
||||
/**
|
||||
* 获取完整路径(带安全检查)
|
||||
* 增强的路径遍历防护
|
||||
*/
|
||||
getFullPath(relativePath) {
|
||||
// 0. 输入验证:检查空字节注入和其他危险字符
|
||||
if (typeof relativePath !== 'string') {
|
||||
throw new Error('无效的路径类型');
|
||||
}
|
||||
|
||||
// 检查空字节注入(%00, \x00)
|
||||
if (relativePath.includes('\x00') || relativePath.includes('%00')) {
|
||||
console.warn('[安全] 检测到空字节注入尝试:', relativePath);
|
||||
throw new Error('路径包含非法字符');
|
||||
}
|
||||
|
||||
// 1. 规范化路径,移除 ../ 等危险路径
|
||||
let normalized = path.normalize(relativePath || '').replace(/^(\.\.[\/\\])+/, '');
|
||||
|
||||
// 2. ✅ 修复:将绝对路径转换为相对路径(解决Linux环境下的问题)
|
||||
// 2. 额外检查:移除路径中间的 .. (防止 a/../../../etc/passwd 绕过)
|
||||
// 解析后的路径不应包含 ..
|
||||
if (normalized.includes('..')) {
|
||||
console.warn('[安全] 检测到目录遍历尝试:', relativePath);
|
||||
throw new Error('路径包含非法字符');
|
||||
}
|
||||
|
||||
// 3. 将绝对路径转换为相对路径(解决Linux环境下的问题)
|
||||
if (path.isAbsolute(normalized)) {
|
||||
// 移除开头的 / 或 Windows 盘符,转为相对路径
|
||||
normalized = normalized.replace(/^[\/\\]+/, '').replace(/^[a-zA-Z]:/, '');
|
||||
}
|
||||
|
||||
// 3. 空字符串或 . 表示根目录
|
||||
// 4. 空字符串或 . 表示根目录
|
||||
if (normalized === '' || normalized === '.') {
|
||||
return this.basePath;
|
||||
}
|
||||
|
||||
// 4. 拼接完整路径
|
||||
// 5. 拼接完整路径
|
||||
const fullPath = path.join(this.basePath, normalized);
|
||||
|
||||
// 5. 安全检查:确保路径在用户目录内(防止目录遍历攻击)
|
||||
if (!fullPath.startsWith(this.basePath)) {
|
||||
// 6. 解析真实路径(处理符号链接)后再次验证
|
||||
const resolvedBasePath = path.resolve(this.basePath);
|
||||
const resolvedFullPath = path.resolve(fullPath);
|
||||
|
||||
// 7. 安全检查:确保路径在用户目录内(防止目录遍历攻击)
|
||||
if (!resolvedFullPath.startsWith(resolvedBasePath)) {
|
||||
console.warn('[安全] 检测到路径遍历攻击:', {
|
||||
input: relativePath,
|
||||
resolved: resolvedFullPath,
|
||||
base: resolvedBasePath
|
||||
});
|
||||
throw new Error('非法路径访问');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user