实操基于Python Flask框架,仅需执行以下命令安装依赖:
``` pip install flask flask-login flask-session ```创建项目文件app.py,完整代码可直接复制运行(模拟漏洞环境):
```python from flask import Flask, request, jsonify, session from flask_login import LoginManager, UserMixin, login_user, login_required, current_user app = Flask(__name__) app.secret_key = 'your-secret-key-keep-it-safe' login_manager = LoginManager() login_manager.init_app(app) 模拟用户数据库 users = { 'userA': {'id': 1, 'role': 'user', 'password': '123'}, 'admin': {'id': 2, 'role': 'admin', 'password': 'admin123'} } class User(UserMixin): pass @login_manager.user_loader def load_user(user_id): for username, data in users.items(): if data['id'] == int(user_id): user = User() user.id = user_id user.role = data['role'] return user return None 模拟存在漏洞的路由:垂直越权(普通用户可访问管理员页面) @app.route('/login', methods=['POST']) def login(): username = request.form.get('username') password = request.form.get('password') if username in users and users[username]['password'] == password: user = User() user.id = str(users[username]['id']) user.role = users[username]['role'] login_user(user) session['user_role'] = user.role return jsonify({'msg': 'login success', 'role': user.role}) return jsonify({'msg': 'invalid credentials'}), 401 @app.route('/admin/user', methods=['GET']) @login_required def admin_user_page(): 未校验角色的漏洞路由 return jsonify({'msg': 'admin user data', 'users': users}) 水平越权模拟路由:根据请求参数中的user_id修改,可改他人信息 @app.route('/user/info', methods=['POST']) @login_required def update_user_info(): update_user_id = request.form.get('user_id') new_info = request.form.get('info') return jsonify({'msg': f'updated user {update_user_id} info to {new_info}'}) if __name__ == '__main__': app.run(port=5000, debug=True) ```执行python app.py,环境将在本地5000端口启动。
用普通用户userA登录,执行以下curl命令获取登录态:
``` curl -c cookie.txt -X POST -d "username=userA&password=123" http://127.0.0.1:5000/login ```用userA的cookie请求管理员路由,返回200则存在垂直越权:
``` curl -b cookie.txt http://127.0.0.1:5000/admin/user ```仍用userA的cookie,修改参数user_id=2(管理员id),执行修改信息请求:
``` curl -b cookie.txt -X POST -d "user_id=2&info=hacked_admin" http://127.0.0.1:5000/user/info ```若请求成功返回更新结果,则存在水平越权漏洞。
在app.py中添加权限校验装饰器,代码如下:
```python def role_required(required_role): def decorator(f): @login_required def wrapper(args, kwargs): 双重校验:session角色 + 当前用户角色 if session.get('user_role') != required_role or current_user.role != required_role: return jsonify({'msg': 'forbidden: insufficient permissions'}), 403 return f(args, kwargs) return wrapper return decorator ```
将原管理员路由的装饰器替换为@role_required('admin'):
修改用户信息修改路由,仅允许修改当前登录用户的信息,代码替换为:
```python @app.route('/user/info', methods=['POST']) @login_required def update_user_info(): new_info = request.form.get('info') 从当前登录用户的ID获取目标用户,禁止使用客户端传入的user_id current_user_id = current_user.id return jsonify({'msg': f'updated user {current_user_id} info to {new_info}'}) ```重新执行漏洞定位步骤:
1. 重新登录userA,获取cookie
2. 用userA的cookie请求/admin/user,应返回403 Forbidden(垂直越权修复成功)
3. 尝试修改user_id=2的信息,应返回403 Forbidden(水平越权修复成功)
禁止将权限角色存储在前端(如cookie、localStorage),必须存储在服务端session或数据库,避免用户篡改角色。
所有敏感路由必须同时验证登录态和权限,不能仅校验一项。
复杂系统可将权限校验封装为中间件,统一应用到所有敏感路由,减少重复代码。












易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。
Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图