2025 强网杯 Web 安全解题思路汇总
secret_value
题目提供了一个 Flask 应用,登录后可在 dashboard 处获取 flag。访问 dashboard 前需经过 login_required 装饰器检查。
def login_required(view_func):
@wraps(view_func)
def wrapped(*args, **kwargs):
uid = request.headers.get('X-User', '0')
print(uid)
if uid == 'anonymous':
flash('Please sign in first.', 'warning')
return redirect(url_for('login'))
try:
uid_int = int(uid)
except (TypeError, ValueError):
flash('Invalid session. Please sign in again.', 'warning')
return redirect(url_for('login'))
user = User.query.filter_by(id=uid_int).first()
if not user:
flash('User not found. Please sign in again.', 'warning')
return redirect(url_for('login'))
g.current_user = user
return view_func(*args, **kwargs)
return wrapped
1️⃣ 读取代理传来的用户 ID
Flask 每次请求时从 HTTP 请求头中取出 X-User。该头由前端的 Go Authorizer 代理自动添加:
- 未登录时:
X-User: anonymous - 已登录时:
X-User: 1(用户 ID)
普通用户注册后无法查看内容,需要伪造管理员身份。虽然中间件的 Go 代码会自动识别并覆盖当前用户的 UID,但可以利用 Hop-by-Hop Headers 的特性删除 Go 生成的 请求头,从而绕过强制校验。

