不安全的访问控制漏洞与防护
字数 1173 2025-11-07 22:15:37

不安全的访问控制漏洞与防护

描述
不安全的访问控制(Broken Access Control)指系统未能有效限制用户对资源或功能的访问权限,导致低权限用户可执行高权限操作(如普通用户访问管理员功能、越权查看他人数据等)。该漏洞在OWASP Top 10 2021中位列榜首,常见于垂直越权(权限提升)和水平越权(数据跨用户访问)。

核心问题

  1. 缺失权限验证:访问敏感功能或数据前未校验用户角色或权限。
  2. 依赖客户端校验:仅通过前端隐藏按钮或接口,但后端未做二次验证。
  3. 可预测的访问参数:通过修改URL中的ID(如/user/123/profile)即可访问他人数据。

漏洞场景示例
假设有一个博客系统,用户可通过以下接口查看自己的文章:

GET /api/posts/12345  
Authorization: Bearer <用户A的Token>

后端逻辑仅验证Token有效性,未检查文章ID 12345是否属于用户A。若用户A将ID改为12346(他人文章),仍可获取数据。


漏洞挖掘与验证步骤

  1. 识别敏感操作

    • 列出所有需权限控制的功能(如用户资料修改、订单查询、管理员后台)。
    • 关注URL参数(如?id=xxx)、请求体参数(如{"userId": "xxx"})。
  2. 修改参数测试越权

    • 水平越权:登录用户A,尝试访问属于用户B的资源(如将/api/orders/100改为/api/orders/101)。
    • 垂直越权:普通用户尝试访问管理员接口(如将/user/dashboard改为/admin/dashboard)。
  3. 工具辅助

    • 使用Burp Suite的"Compare Site Maps"对比不同权限用户的接口范围。
    • 自动化扫描器(如Arachni)检测常见越权模式。

防护方案

  1. 强制权限校验

    • 所有敏感操作需经过后端统一的权限检查中间件,例如:
    # 伪代码示例:校验数据归属权
    def get_user_post(post_id):
        current_user = get_current_user()
        post = Post.query.get(post_id)
        if post.user_id != current_user.id:
            raise PermissionDeniedError()
        return post
    
  2. 最小权限原则

    • 用户默认仅拥有最低必要权限,角色权限分离(如RBAC模型)。
  3. 不可预测的标识符

    • 使用随机UUID替代自增ID(如/api/posts/a1b2c3d4而非/api/posts/123)。
  4. 自动化测试

    • 编写单元测试模拟不同角色用户访问受限资源,确保返回403状态码。
  5. 日志与监控

    • 记录越权访问尝试,实时告警异常行为(如同一Token频繁访问不同用户数据)。

进阶案例:基于条件的访问控制漏洞
场景:博客平台允许用户编辑文章,但需满足两个条件:

  • 用户是文章所有者。
  • 文章状态为“草稿”。

漏洞代码:

UPDATE posts SET content = '恶意内容' 
WHERE id = 123 AND status = 'draft';  -- 未校验用户身份!

攻击者可通过修改ID编辑他人草稿文章。

修复方案:

UPDATE posts SET content = '恶意内容' 
WHERE id = 123 AND user_id = 当前用户ID AND status = 'draft';

总结
不安全的访问控制本质是信任边界模糊。防护核心在于:

  • 服务端强制校验:永不信任客户端传递的参数。
  • 权限与数据绑定:查询数据时自动关联当前用户身份。
  • 标准化框架:使用Spring Security、CASL等成熟框架减少手动实现误差。
不安全的访问控制漏洞与防护 描述 不安全的访问控制(Broken Access Control)指系统未能有效限制用户对资源或功能的访问权限,导致低权限用户可执行高权限操作(如普通用户访问管理员功能、越权查看他人数据等)。该漏洞在OWASP Top 10 2021中位列榜首,常见于垂直越权(权限提升)和水平越权(数据跨用户访问)。 核心问题 缺失权限验证 :访问敏感功能或数据前未校验用户角色或权限。 依赖客户端校验 :仅通过前端隐藏按钮或接口,但后端未做二次验证。 可预测的访问参数 :通过修改URL中的ID(如 /user/123/profile )即可访问他人数据。 漏洞场景示例 假设有一个博客系统,用户可通过以下接口查看自己的文章: 后端逻辑仅验证Token有效性,未检查文章ID 12345 是否属于用户A。若用户A将ID改为 12346 (他人文章),仍可获取数据。 漏洞挖掘与验证步骤 识别敏感操作 : 列出所有需权限控制的功能(如用户资料修改、订单查询、管理员后台)。 关注URL参数(如 ?id=xxx )、请求体参数(如 {"userId": "xxx"} )。 修改参数测试越权 : 水平越权 :登录用户A,尝试访问属于用户B的资源(如将 /api/orders/100 改为 /api/orders/101 )。 垂直越权 :普通用户尝试访问管理员接口(如将 /user/dashboard 改为 /admin/dashboard )。 工具辅助 : 使用Burp Suite的"Compare Site Maps"对比不同权限用户的接口范围。 自动化扫描器(如Arachni)检测常见越权模式。 防护方案 强制权限校验 : 所有敏感操作需经过后端统一的权限检查中间件,例如: 最小权限原则 : 用户默认仅拥有最低必要权限,角色权限分离(如RBAC模型)。 不可预测的标识符 : 使用随机UUID替代自增ID(如 /api/posts/a1b2c3d4 而非 /api/posts/123 )。 自动化测试 : 编写单元测试模拟不同角色用户访问受限资源,确保返回403状态码。 日志与监控 : 记录越权访问尝试,实时告警异常行为(如同一Token频繁访问不同用户数据)。 进阶案例:基于条件的访问控制漏洞 场景:博客平台允许用户编辑文章,但需满足两个条件: 用户是文章所有者。 文章状态为“草稿”。 漏洞代码: 攻击者可通过修改ID编辑他人草稿文章。 修复方案: 总结 不安全的访问控制本质是信任边界模糊。防护核心在于: 服务端强制校验 :永不信任客户端传递的参数。 权限与数据绑定 :查询数据时自动关联当前用户身份。 标准化框架 :使用Spring Security、CASL等成熟框架减少手动实现误差。