水平越权怎么预防?

wen 网络安全 54

本文目录导读:

水平越权怎么预防?

  1. 核心原则:基于用户身份的细粒度访问控制
  2. 架构设计:消除或替代可预测/可枚举的资源ID
  3. 后端API设计:参数绑定与校验
  4. 测试与审计机制
  5. 特殊的场景处理
  6. 总结:预防水平越权的“黄金法则”

水平越权(Horizontal Privilege Escalation)是指攻击者利用漏洞,访问或操作与自己同级别但属于其他用户的数据或功能(普通用户A查看或修改了普通用户B的订单)。

预防水平越权没有单一的“银弹”,需要从架构设计、编码规范、访问控制、数据隔离等多个层面进行综合治理,以下是核心的预防策略:

核心原则:基于用户身份的细粒度访问控制

这是最根本的预防措施。永远不要信任用户传入的ID(如 user_idorder_id)来标识“谁”在操作。

  • 从Session/Token中获取当前用户ID: 不要从前端请求的参数(如URL的 ?user_id=123)中获取当前操作者的身份,必须从服务器端维护的安全会话(Session)或签名的JWT(JSON Web Token)中提取。

  • 绑定数据所有权: 在执行任何涉及用户数据的操作(查询、修改、删除)前,必须验证该数据的所有者ID是否等于当前登录用户的ID。

    代码示例(避免)

    # 危险!直接使用URL传入的user_id
    user_id = request.GET.get('user_id')
    order = db.get_order(order_id, user_id=user_id) # 用户A可以传入user_id=B来查B的订单
    return order

    代码示例(推荐)

    # 安全!从Session获取当前用户ID
    current_user_id = session['user_id']
    order = db.get_order(order_id)
    # 关键检查:确保订单属于当前用户
    if order.user_id != current_user_id:
        raise PermissionDenied("无权访问该订单")
    return order

架构设计:消除或替代可预测/可枚举的资源ID

水平越权常利用可枚举的ID(如自增ID、连续数字)遍历其他用户的数据。

  • 使用UUID或哈希ID: 将自增整数ID替换为全局唯一标识符(UUID,Universally Unique Identifier)或非连续的哈希ID,这能防止攻击者通过简单递增ID来猜测其他用户的数据。
  • 使用间接引用: 不让用户直接传递“订单ID”,而是传递一个“订单访问令牌”或“引用ID”,服务器内部映射回真实ID,这样外部无法获取真实ID的规律。

后端API设计:参数绑定与校验

  • 拒绝无关参数: API接口只接收处理当前业务逻辑所必须的参数,如果接口需要查询当前用户的订单,就不应该设计成接收 other_user_id 作为参数。

  • 强制绑定上下文: 在后端服务的Service层或数据访问层,强制将查询条件与当前用户ID绑定。

    例子:一个查询用户订单列表的API,后端SQL应类似:SELECT * FROM orders WHERE user_id = :current_user_id,而不是 SELECT * FROM orders WHERE user_id = :requested_user_id(除非是管理员功能)。

测试与审计机制

  • 渗透测试专项: 在安全测试中,专门针对所有带有“用户特定数据”的接口进行测试,测试方法:用户A登录,记录所有操作,然后使用用户B的Token或Cookie,尝试调用用户A曾操作过的API(修改用户A的ID、订单ID等)。
  • 动态权限检查: 使用自动化工具(如Burp Suite的Autorize、AuthMatrix插件)批量扫描所有API端点,检查是否存在未授权的跨用户数据访问。
  • 日志审计: 记录所有对敏感数据的访问操作,包括操作用户ID、操作对象ID、操作类型和时间,一旦发生越权泄漏,可以追溯和分析。

特殊的场景处理

  • 文件/资源访问: 访问其他用户上传的文件(如头像、附件)时也要注意,如果文件路径或ID是可预测的(如 /files/user_123/photo.jpg),业务逻辑也必须验证当前用户是否有权访问该路径下的文件,通常建议使用专门的文件服务,并基于Token校验。
  • 缓存与CDN: 如果CDN或缓存服务器没有正确配置,攻击者可能通过猜测或遍历资源的URL来访问其他用户的私有内容,确保动态、私有的用户内容使用鉴权URL或私有缓存策略。

预防水平越权的“黄金法则”

层面 核心操作 为什么这样做
身份识别 从Session/Token获取用户ID,绝不信任前端传入的ID。 防止攻击者伪装成其他用户。
权限校验 在每一次数据访问前,检查数据的所有者是否等于当前用户。 确保操作在合法范围内。
ID设计 使用UUID/哈希ID替代自增整数ID。 增加猜测和遍历的难度。
接口设计 API只接受必要参数,拒绝无关的用户标识。 减少攻击面。
测试验证 定期进行跨用户越权专项渗透测试 发现隐藏的漏洞。

简单一句话:服务端永远要问一句:“这个数据,你真的有权利动吗?”

抱歉,评论功能暂时关闭!