feat: 安全增强 + 删除密码重置申请功能 + 登录提醒开关

安全增强:
- 新增 SSRF、XXE、模板注入、敏感路径探测检测规则
- security/constants.py: 添加新的威胁类型和检测模式
- security/threat_detector.py: 实现新检测逻辑

删除密码重置申请功能:
- 移除 /api/password_resets 相关API
- 删除 password_reset_requests 数据库表
- 前端移除密码重置申请页面和菜单
- 用户只能通过邮��找回密码,未绑定邮箱需联系管理员

登录提醒全局开关:
- email_service.py: 添加 login_alert_enabled 字段
- routes/api_auth.py: 检查开关状态再发送登录提醒
- EmailPage.vue: 添加新设备登录提醒开关

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-27 12:08:36 +08:00
parent 4ba933b001
commit 89f3fd9759
65 changed files with 555 additions and 784 deletions

View File

@@ -12,6 +12,10 @@ THREAT_TYPE_SQL_INJECTION = "sql_injection"
THREAT_TYPE_XSS = "xss"
THREAT_TYPE_PATH_TRAVERSAL = "path_traversal"
THREAT_TYPE_COMMAND_INJECTION = "command_injection"
THREAT_TYPE_SSRF = "ssrf"
THREAT_TYPE_XXE = "xxe"
THREAT_TYPE_TEMPLATE_INJECTION = "template_injection"
THREAT_TYPE_SENSITIVE_PATH_PROBE = "sensitive_path_probe"
# ==================== Scores ====================
@@ -23,6 +27,10 @@ SCORE_SQL_INJECTION = 90
SCORE_XSS = 70
SCORE_PATH_TRAVERSAL = 60
SCORE_COMMAND_INJECTION = 85
SCORE_SSRF = 75
SCORE_XXE = 85
SCORE_TEMPLATE_INJECTION = 70
SCORE_SENSITIVE_PATH_PROBE = 40
# ==================== JNDI (Log4j) ====================
@@ -75,6 +83,33 @@ CMD_INJECTION_OPERATOR_WITH_CMD_PATTERN = (
CMD_INJECTION_SUBSHELL_PATTERN = r"(?:`[^`]{1,200}`|\$\([^)]{1,200}\))"
# ==================== SSRF ====================
SSRF_LOCALHOST_URL_PATTERN = r"\bhttps?\s*:\s*//\s*(?:127\.0\.0\.1\b|localhost\b|0\.0\.0\.0\b)"
SSRF_INTERNAL_IP_URL_PATTERN = r"\bhttps?\s*:\s*//\s*(?:10\.|192\.168\.|172\.(?:1[6-9]|2[0-9]|3[0-1])\.)"
SSRF_DANGEROUS_PROTOCOL_PATTERN = r"\b(?:file|gopher|dict)\s*:\s*//"
# ==================== XXE ====================
XXE_DOCTYPE_PATTERN = r"<!\s*doctype\b|\bdoctype\b"
XXE_ENTITY_PATTERN = r"<!\s*entity\b|\bentity\b"
XXE_SYSTEM_PUBLIC_PATTERN = r"\b(?:system|public)\b"
# ==================== Template Injection ====================
TEMPLATE_JINJA_EXPR_PATTERN = r"\{\{\s*[^}]{0,200}\s*\}\}"
TEMPLATE_JINJA_STMT_PATTERN = r"\{%\s*[^%]{0,200}\s*%\}"
TEMPLATE_VELOCITY_DIRECTIVE_PATTERN = r"#\s*(?:set|if)\b"
# ==================== Sensitive Path Probing ====================
SENSITIVE_PATH_DOTFILES_PATTERN = r"/\.(?:git|svn|env)(?:/|\b|$)"
SENSITIVE_PATH_PROBE_PATTERN = r"/(?:actuator|phpinfo|wp-admin)(?:/|\b|$)"
# ==================== Compiled Regex ====================
_FLAGS = re.IGNORECASE | re.MULTILINE
@@ -95,3 +130,17 @@ PATH_TRAVERSAL_RE = re.compile(PATH_TRAVERSAL_PATTERN, _FLAGS)
CMD_INJECTION_OPERATOR_WITH_CMD_RE = re.compile(CMD_INJECTION_OPERATOR_WITH_CMD_PATTERN, _FLAGS)
CMD_INJECTION_SUBSHELL_RE = re.compile(CMD_INJECTION_SUBSHELL_PATTERN, _FLAGS)
SSRF_LOCALHOST_URL_RE = re.compile(SSRF_LOCALHOST_URL_PATTERN, _FLAGS)
SSRF_INTERNAL_IP_URL_RE = re.compile(SSRF_INTERNAL_IP_URL_PATTERN, _FLAGS)
SSRF_DANGEROUS_PROTOCOL_RE = re.compile(SSRF_DANGEROUS_PROTOCOL_PATTERN, _FLAGS)
XXE_DOCTYPE_RE = re.compile(XXE_DOCTYPE_PATTERN, _FLAGS)
XXE_ENTITY_RE = re.compile(XXE_ENTITY_PATTERN, _FLAGS)
XXE_SYSTEM_PUBLIC_RE = re.compile(XXE_SYSTEM_PUBLIC_PATTERN, _FLAGS)
TEMPLATE_JINJA_EXPR_RE = re.compile(TEMPLATE_JINJA_EXPR_PATTERN, _FLAGS)
TEMPLATE_JINJA_STMT_RE = re.compile(TEMPLATE_JINJA_STMT_PATTERN, _FLAGS)
TEMPLATE_VELOCITY_DIRECTIVE_RE = re.compile(TEMPLATE_VELOCITY_DIRECTIVE_PATTERN, _FLAGS)
SENSITIVE_PATH_DOTFILES_RE = re.compile(SENSITIVE_PATH_DOTFILES_PATTERN, _FLAGS)
SENSITIVE_PATH_PROBE_RE = re.compile(SENSITIVE_PATH_PROBE_PATTERN, _FLAGS)