不安全的直接对象引用(IDOR)漏洞与防护
字数 1119 2025-11-03 08:33:37
不安全的直接对象引用(IDOR)漏洞与防护
题目描述:
不安全的直接对象引用(IDOR)是一种常见的访问控制漏洞,发生在应用程序直接使用用户提供的输入(如URL参数、表单字段)来访问内部对象(如数据库记录、文件、账号数据)时。攻击者通过修改参数值(例如将user_id=123改为user_id=124),越权访问其他用户的敏感数据或执行未授权操作。例如,网银应用中若通过/account?number=888直接查询账户,攻击者可能通过遍历账户编号窃取信息。
解题过程:
-
理解漏洞本质:
- 根本原因是缺乏权限验证。应用程序假设用户提供的参数(如ID)合法,但未检查"当前用户是否有权访问该ID对应的资源"。
- 关键区别:参数值本身可能有效(如
124是真实账户),但访问行为应被禁止。
-
漏洞发现方法:
- 测试步骤:
- 登录系统后,观察URL、Cookie或API请求中的对象标识符(如数字、文件名)。
- 修改标识符(如递增ID、尝试其他用户名),查看是否返回越权数据。
- 尝试将普通用户参数改为管理员参数(如
role=admin),检查权限提升漏洞。
- 示例:
- 正常请求:
GET /api/invoice?id=100(用户A访问自己的发票)。 - 攻击请求:
GET /api/invoice?id=101(用户A越权访问用户B的发票)。
- 正常请求:
- 测试步骤:
-
防护方案设计:
- 原则:所有请求必须经过权限验证,而非依赖"隐藏"参数或前端控制。
- 核心步骤:
- 身份认证:首先确认用户身份(如通过Session或Token)。
- 映射校验:建立"用户-可访问对象"的映射关系,例如:
- 数据库查询时关联用户ID:
SELECT * FROM invoices WHERE id = ? AND user_id = ?; - 或使用访问控制列表(ACL)验证权限。
- 数据库查询时关联用户ID:
- 间接引用:避免直接暴露内部标识符(如数据库自增ID),改用随机且不可预测的令牌(如UUID)或加密后的参数。
- 标准化错误处理:越权请求返回403 Forbidden而非404,避免信息泄露。
-
实际代码对比:
- 漏洞代码(直接使用用户输入):
invoice_id = request.GET.get('id') invoice = Invoice.objects.get(id=invoice_id) # 未校验当前用户权限 - 修复代码(关联用户上下文):
invoice = Invoice.objects.get(id=invoice_id, user=request.user) # 自动过滤权限 if not invoice: return HttpResponse("Forbidden", status=403)
- 漏洞代码(直接使用用户输入):
-
进阶防护措施:
- 分层验证:结合角色权限(如管理员、普通用户)与数据级权限(如用户只能操作自己的数据)。
- 日志监控:记录所有敏感操作,检测异常访问模式(如同一用户频繁访问不同ID)。
- 自动化测试:使用工具(如Burp Suite)扫描IDOR漏洞,或编写单元测试模拟越权请求。
总结:
IDOR漏洞的防护核心是强制每次访问都经过权限验证,通过"用户-资源"绑定、间接引用和最小权限原则,确保参数不可被滥用。在代码审查时,需重点关注所有依赖用户输入的对象访问逻辑是否包含权限校验。