本项目实现了多层安全防护:请求频率限制、机器人检测、IP黑名单、登录安全、API认证。
| 文件 | 功能 |
|---|---|
utils/rate_limiter.py |
请求频率限制 |
utils/bot_detector.py |
机器人/脚本检测 |
utils/login_rate_limiter.py |
登录频率限制 |
utils/login_security.py |
登录安全 |
middleware/ip_logger.py |
IP访问记录与黑名单检查 |
utils/request_auth.py |
API请求认证(签名验证) |
utils/permission_checker.py |
用户权限检查 |
- 基于内存的滑动窗口计数器
- 使用IP地址作为限制key
- 自动清理过期记录(5分钟间隔)
from utils.rate_limiter import rate_limit
@app.route('/api/xxx')
@rate_limit(limit=30, window=60) # 每分钟30次
def xxx():
pass| 装饰器 | 限制 | 适用场景 |
|---|---|---|
@strict_rate_limit |
10次/分钟 | 敏感操作(登录、注册) |
@normal_rate_limit |
30次/分钟 | 普通API |
@loose_rate_limit |
100次/分钟 | 高频操作(播放状态同步) |
{
"error": "请求过于频繁,请稍后再试",
"error_type": "RateLimitError",
"retry_after": 30
}- HTTP状态码:429
- 响应头:
Retry-After,X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset
| 检测项 | 风险分数 | 说明 |
|---|---|---|
| 缺少User-Agent | +30 | 正常浏览器必有 |
| User-Agent过短 | +20 | 可能伪造 |
| 可疑UA关键词 | +40 | python/requests/curl/bot等 |
| 缺少Accept/Accept-Language | +8/项 | 浏览器常见头 |
| 请求频率过高 | +25 | 超过20次/分钟 |
| 缺少Referer(登录) | +15 | 可能脚本直接调用 |
| IP在黑名单 | +50 | 直接高分 |
| 分数范围 | 级别 | 处理 |
|---|---|---|
| 0-19 | low | 正常放行 |
| 20-39 | medium | 记录日志 |
| 40-59 | high | 警告日志 |
| 60+ | critical | 严重警告 |
BotDetector.CONFIG = {
'enabled': True, # 总开关
'cache_ttl': 300, # 检测结果缓存5分钟
'min_risk_score': 30, # 达到此分数认定为机器人
'frequency_check': True, # 启用频率检测
'frequency_threshold': 20, # 每分钟请求阈值
'skip_api_endpoints': True, # API端点跳过Referer检查
}from utils.bot_detector import bot_detector
# 检测
result = bot_detector.detect_bot_activity(
user=user,
action='search',
context={'keyword': keyword}
)
# 异步记录(不阻塞主流程)
if result['is_bot']:
bot_detector.log_suspicious_activity_async(user, 'search', result)BotDetector.IP_WHITELIST = ['127.0.0.1', 'localhost', '::1']# app.py before_request
from middleware.ip_logger import check_ip_blacklist
is_blacklisted, ip = check_ip_blacklist()
if is_blacklisted:
return {'error': 'Access denied'}, 403自动跳过以下请求的记录:
- 静态资源(.css, .js, .png等)
/static/目录- API请求(
/api/) - AJAX请求
- 管理后台(动态路径,默认
/debugbox)
ip_blacklist- 黑名单ip_access_log- 访问记录
- 同一IP连续失败后增加等待时间
- 防止暴力破解
- 支持渐进式封锁
# 前端发送
{
"username": "xxx",
"password": "xxx",
"timestamp": "1234567890",
"signature": "hmac_sha256_signature"
}
# 后端验证
from utils.request_auth import verify_signature
if not verify_signature(signature, timestamp, params, keys):
return api_error('登录签名无效')- 哈希算法:
pbkdf2:sha256:260000 - 最小长度:6位
SESSION_COOKIE_SECURE = True # 生产环境HTTPS only
SESSION_COOKIE_HTTPONLY = True # 防XSS
SESSION_COOKIE_SAMESITE = 'Lax' # 防CSRF
PERMANENT_SESSION_LIFETIME = 7天- 替代前端存储密码
- 32字节安全随机token
- 7天有效期
- 每次使用后轮换
# 登录/注册成功后重新生成session ID
session.clear()
session.permanent = True
session['user_id'] = user.idUserPermission.max_devices- 最大设备数(默认1)- 0表示无限制
- 超限时返回403
- 管理后台可远程踢出设备
- 用户可在其他设备退出
统一权限检查
from utils.decorators import require_permission
@app.route('/api/xxx')
@require_permission(require_login=True, check_interface=True)
def xxx(user):
pass系统使用 disable-devtool 库实现前端反调试保护,防止用户通过开发者工具查看和修改前端代码。
重要:反调试仅在 PC 端生效,移动端自动禁用以保证 PWA 息屏播放性能。
反调试代码在 HTML <head> 中加载,确保最早执行,并使用本地化脚本避免 CDN 问题:
<!-- 反调试保护(仅PC端,移动端禁用以保证息屏播放性能) -->
<script>
(function(){
// 移动端检测 - 移动端禁用反调试
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
if (isMobile) { window.__ANTI_DEBUG_DISABLED__ = true; return; }
// 检查后台调试状态
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/anti-debug/config', false);
try {
xhr.send();
if (xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
if (data.debug_enabled) window.__ANTI_DEBUG_DISABLED__ = true;
}
} catch(e) {}
})();
</script>
<script>
if (!window.__ANTI_DEBUG_DISABLED__) {
document.write('<script src="/static/js/disable-devtool.min.js" disable-devtool-auto interval="500"><\/script>');
}
</script>| 功能 | 说明 |
|---|---|
| 禁用 F12 | 阻止 F12 快捷键 |
| 禁用 Ctrl+Shift+I/J/C | 阻止开发者工具快捷键 |
| 禁用 Ctrl+U | 阻止查看源码 |
| 禁用右键菜单 | 阻止右键检查元素 |
| 窗口尺寸检测 | 检测开发者工具面板 |
| debugger 语句 | 高频 debugger 断点 |
| console 对象检测 | 检测控制台打开 |
| 性能检测 | 检测调试器导致的性能下降 |
- 后台调试模式开启时(
/debug页面),反调试自动禁用 - 移动端自动禁用,保证 PWA 息屏播放性能
- 配置存储在
logs/debug_config.json - 通过
/api/anti-debug/config接口获取状态
# routes/main.py
@app.route('/api/anti-debug/config', methods=['GET'])
def get_anti_debug_config():
from utils.debug_logger import is_debug_enabled
return jsonify({
'success': True,
'debug_enabled': is_debug_enabled()
})当本地脚本加载失败时,没有外部 CDN 备用,因为本地文件更可靠。
但 static/js/anti-debug.js 仍作为历史遗留代码存在(已不再使用)。
- 反调试不是绝对安全的,有经验的开发者仍可绑过
- 主要目的是增加逆向难度,保护普通用户
- 敏感逻辑应放在后端,不要依赖前端保护
- 调试时记得开启后台调试模式
开发新功能时检查:
- 所有用户输入是否转义后再渲染
- 前端验证是否与后端一致
- DOM 操作前是否检查元素存在
- 事件监听器是否正确清理
- 数值计算是否处理边界情况
- 配置值是否从统一位置获取
- 检查是否有异常请求
- 调整
rate_limit参数 - 检查是否有爬虫
- 检查 User-Agent 是否正常
- 调整
BotDetector.CONFIG['min_risk_score'] - 添加IP到白名单
- 管理后台 → IP管理 → 移除黑名单
- 检查封禁原因
- 检查前端时间戳是否正确
- 检查密钥版本是否同步
- 刷新页面重试