修复多项安全漏洞
安全修复清单: 1. 验证码改为图片方式返回,防止明文泄露 2. CORS配置从环境变量读取,不再使用通配符"*" 3. VIP API添加@admin_required装饰器,统一认证 4. 用户登录统一错误消息,防止用户枚举 5. IP限流不再信任X-Forwarded-For头,防止伪造绕过 6. 密码强度要求提升(8位+字母+数字) 7. 日志不���记录完整session/cookie内容,防止敏感信息泄露 8. XSS防护:日志输出和Bug反馈内容转义HTML 9. SQL注入防护:LIKE查询参数转义 10. 路径遍历防护:截图目录白名单验证 11. 验证码重放防护:验证前删除验证码 12. 数据库连接池健康检查 13. 正则DoS防护:限制数字匹配长度 14. Account类密码私有化,__repr__不暴露密码 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
29
database.py
29
database.py
@@ -630,7 +630,10 @@ def remove_user_vip(user_id):
|
||||
|
||||
|
||||
def is_user_vip(user_id):
|
||||
"""检查用户是否是VIP"""
|
||||
"""检查用户是否是VIP
|
||||
|
||||
注意:数据库中存储的时间统一使用CST(Asia/Shanghai)时区
|
||||
"""
|
||||
cst_tz = pytz.timezone("Asia/Shanghai")
|
||||
user = get_user_by_id(user_id)
|
||||
|
||||
@@ -638,9 +641,12 @@ def is_user_vip(user_id):
|
||||
return False
|
||||
|
||||
try:
|
||||
# 时区处理说明:数据库存储的是CST时间字符串
|
||||
# 如果将来改为UTC存储,需要修改此处逻辑
|
||||
expire_time_naive = datetime.strptime(user['vip_expire_time'], '%Y-%m-%d %H:%M:%S')
|
||||
expire_time = cst_tz.localize(expire_time_naive)
|
||||
return datetime.now(cst_tz) < expire_time
|
||||
now = datetime.now(cst_tz)
|
||||
return now < expire_time
|
||||
except (ValueError, AttributeError) as e:
|
||||
print(f"检查VIP状态失败 (user_id={user_id}): {e}")
|
||||
return False
|
||||
@@ -1137,8 +1143,11 @@ def get_task_logs(limit=100, offset=0, date_filter=None, status_filter=None,
|
||||
params.append(user_id_filter)
|
||||
|
||||
if account_filter:
|
||||
where_clauses.append("tl.username LIKE ?")
|
||||
params.append(f"%{account_filter}%")
|
||||
# 转义LIKE中的特殊字符,防止绕过过滤
|
||||
from app_security import sanitize_sql_like_pattern
|
||||
safe_filter = sanitize_sql_like_pattern(account_filter)
|
||||
where_clauses.append("tl.username LIKE ? ESCAPE '\\'")
|
||||
params.append(f"%{safe_filter}%")
|
||||
|
||||
where_sql = " AND ".join(where_clauses)
|
||||
|
||||
@@ -1409,16 +1418,24 @@ def clean_old_operation_logs(days=30):
|
||||
# ==================== Bug反馈管理 ====================
|
||||
|
||||
def create_bug_feedback(user_id, username, title, description, contact=''):
|
||||
"""创建Bug反馈"""
|
||||
"""创建Bug反馈(带XSS防护)"""
|
||||
from app_security import escape_html
|
||||
|
||||
with db_pool.get_db() as conn:
|
||||
cursor = conn.cursor()
|
||||
cst_tz = pytz.timezone("Asia/Shanghai")
|
||||
cst_time = datetime.now(cst_tz).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# 安全修复:转义用户输入,防止存储型XSS攻击
|
||||
safe_title = escape_html(title) if title else ''
|
||||
safe_description = escape_html(description) if description else ''
|
||||
safe_contact = escape_html(contact) if contact else ''
|
||||
safe_username = escape_html(username) if username else ''
|
||||
|
||||
cursor.execute('''
|
||||
INSERT INTO bug_feedbacks (user_id, username, title, description, contact, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
''', (user_id, username, title, description, contact, cst_time))
|
||||
''', (user_id, safe_username, safe_title, safe_description, safe_contact, cst_time))
|
||||
|
||||
conn.commit()
|
||||
return cursor.lastrowid
|
||||
|
||||
Reference in New Issue
Block a user