记一次有趣的逻辑漏洞挖洞经历
字数 1142 2025-08-18 11:35:40
逻辑漏洞挖掘实战:水平越权漏洞分析与复现
漏洞概述
本文详细分析一个在线教育平台(MOOC系统)中存在的水平越权漏洞,该漏洞允许攻击者通过构造特定请求删除其他用户的笔记、评论等数据。漏洞被评为中危级别,属于典型的逻辑缺陷。
漏洞发现环境
- 目标系统:在线教育平台(MOOC系统)
- 开放功能:用户注册、登录、视频学习、笔记记录、评论等
- 测试工具:Burp Suite
漏洞发现过程
1. 初步侦察
- 注册测试账号,了解系统功能模块
- 重点关注用户数据交互功能:
- 个人信息修改(XSS测试)
- 头像上传(文件上传测试)
- 笔记、评论、收藏等用户生成内容功能
2. 笔记功能分析
创建笔记请求包分析:
POST /api/note/create HTTP/1.1
Content-Type: application/json
{
"content": "测试笔记内容",
"resourceId": 133,
"videoId": 42
}
关键发现:
resourceId参数不从1开始,而是跳跃到133- 推测ID生成机制为全站笔记总数+1,与用户无关
删除笔记请求包分析:
POST /api/note/delete HTTP/1.1
Content-Type: application/json
{
"id": 134,
"content": "测试笔记内容",
"videoId": 42
}
关键发现:
- 删除操作仅需要
id参数 - 其他参数(content, videoId)后端未做验证
- ID生成机制验证:不同用户创建的笔记ID连续递增
3. 漏洞验证
- 使用账号A创建笔记,记录ID
- 使用账号B创建笔记,记录ID
- 使用账号A构造删除请求,修改ID为B的笔记ID
- 验证B的笔记是否被删除
漏洞原理分析
后端处理逻辑缺陷
创建逻辑:
- 接收前端POST请求
- 从数据库获取当前笔记总数N
- 为新笔记分配ID=N+1
- 存储笔记内容,不严格绑定用户身份
删除逻辑:
- 接收前端POST请求
- 提取请求中的ID参数
- 直接删除对应ID的笔记记录
- 不验证请求用户是否有操作权限
根本原因
- 缺乏权限验证:后端未验证请求用户是否拥有对目标数据的操作权限
- 过度依赖前端参数:仅依赖易篡改的ID参数执行敏感操作
- 全局ID生成策略:使用连续递增的全局ID而非用户关联ID
漏洞利用影响
- 可删除任意用户的笔记、评论等数据
- 通过ID遍历可批量删除全站用户数据
- 可能造成数据完整性破坏和服务可用性问题
修复建议
1. 权限验证机制
# 错误示范 - 无权限验证
def delete_note(request):
note_id = request.POST.get('id')
Note.objects.filter(id=note_id).delete()
# 正确示范 - 添加权限验证
def delete_note(request):
note_id = request.POST.get('id')
Note.objects.filter(id=note_id, user=request.user).delete()
2. ID生成策略改进
- 使用UUID或其他非连续ID生成方式
- 将用户ID作为数据主键的一部分
3. 防御深度策略
- 前端:在请求中添加用户身份令牌
- 后端:
- 验证用户会话
- 验证数据所有权
- 记录操作日志
- 数据库:设计用户关联的数据结构
测试方法论
- 功能映射:列出所有数据操作功能点
- 参数分析:识别请求中的关键参数
- 权限测试:
- 使用不同账号操作相同数据
- 修改参数尝试越权操作
- ID遍历:测试可预测ID的操纵可能性
总结
该漏洞展示了Web应用中常见的逻辑缺陷模式:
- 过度信任客户端提供的数据
- 缺乏必要的权限验证
- 不安全的ID生成和管理策略
安全开发应遵循最小权限原则,对所有数据操作实施严格的权限验证,避免仅依赖易篡改的参数进行敏感操作。