Skip to content

Security: SuperheroerN/ting_app

Security

docs/security.md

安全机制

概述

本项目实现了多层安全防护:请求频率限制、机器人检测、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 用户权限检查

请求频率限制 (rate_limiter.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

机器人检测 (bot_detector.py)

检测项目与评分

检测项 风险分数 说明
缺少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)

IP白名单

BotDetector.IP_WHITELIST = ['127.0.0.1', 'localhost', '::1']

IP黑名单 (middleware/ip_logger.py)

检查流程

# 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 - 访问记录

登录安全

登录频率限制 (login_rate_limiter.py)

  • 同一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安全 (app.py)

SESSION_COOKIE_SECURE = True      # 生产环境HTTPS only
SESSION_COOKIE_HTTPONLY = True    # 防XSS
SESSION_COOKIE_SAMESITE = 'Lax'   # 防CSRF
PERMANENT_SESSION_LIFETIME = 7

Remember Token

  • 替代前端存储密码
  • 32字节安全随机token
  • 7天有效期
  • 每次使用后轮换

会话固定攻击防护

# 登录/注册成功后重新生成session ID
session.clear()
session.permanent = True
session['user_id'] = user.id

设备管理

设备数限制

  • UserPermission.max_devices - 最大设备数(默认1)
  • 0表示无限制
  • 超限时返回403

设备踢出

  • 管理后台可远程踢出设备
  • 用户可在其他设备退出

@require_permission

统一权限检查

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 仍作为历史遗留代码存在(已不再使用)。

注意事项

  1. 反调试不是绝对安全的,有经验的开发者仍可绑过
  2. 主要目的是增加逆向难度,保护普通用户
  3. 敏感逻辑应放在后端,不要依赖前端保护
  4. 调试时记得开启后台调试模式

安全审计检查清单

开发新功能时检查:

  • 所有用户输入是否转义后再渲染
  • 前端验证是否与后端一致
  • DOM 操作前是否检查元素存在
  • 事件监听器是否正确清理
  • 数值计算是否处理边界情况
  • 配置值是否从统一位置获取

常见问题

频繁触发频率限制

  1. 检查是否有异常请求
  2. 调整 rate_limit 参数
  3. 检查是否有爬虫

误判为机器人

  1. 检查 User-Agent 是否正常
  2. 调整 BotDetector.CONFIG['min_risk_score']
  3. 添加IP到白名单

IP被误封

  1. 管理后台 → IP管理 → 移除黑名单
  2. 检查封禁原因

登录签名失败

  1. 检查前端时间戳是否正确
  2. 检查密钥版本是否同步
  3. 刷新页面重试

There aren’t any published security advisories