什么是水平越权?

水平越权(Horizontal Privilege Escalation)是一种安全漏洞,指攻击者通过篡改请求或参数,访问与自己权限等级相同的其他用户的资源或数据。
这种攻击通常发生在身份验证机制未正确检查访问者身份的系统中。


水平越权示例

简单示例

一个在线银行系统允许用户查看自己的账户信息。
前端请求的URL可能如下:

GET /account/details?id=123

假设攻击者登录后,知道自己的账户ID为123,但尝试将URL中的id参数改为124

GET /account/details?id=124

如果后端没有验证用户是否有权限访问ID为124的账户信息,那么攻击者就可以成功获取其他用户的敏感信息。


如何防止水平越权?

防止水平越权的核心是严格验证用户对资源的权限。以下是具体防护措施:

1. 在后端验证资源归属

在处理请求时,后端必须检查资源是否属于当前用户。
以订单详情为例:

// 示例:Spring Boot 后端验证
@GetMapping("/order/details")
public Order getOrderDetails(@RequestParam int orderId, Authentication authentication) {
    String currentUser = authentication.getName(); // 当前登录用户
    Order order = orderService.getOrderById(orderId);

    if (!order.getOwner().equals(currentUser)) {
        throw new AccessDeniedException("您无权访问此订单!");
    }
    return order;
}

2. 使用Token或Session验证

  • 通过Session或JWT(JSON Web Token)携带用户身份信息,避免依赖用户传递的敏感参数。
  • 在后端对请求进行二次校验。

示例:JWT验证订单归属

@GetMapping("/order/details")
public Order getOrderDetails(@RequestParam int orderId, @RequestHeader("Authorization") String token) {
    String currentUser = jwtService.extractUsername(token); // 从JWT提取用户名
    Order order = orderService.getOrderById(orderId);
    if (!order.getOwner().equals(currentUser)) {
        throw new AccessDeniedException("您无权访问此订单!");
    }
    return order;
}

3. 最小化可控参数

  • 避免将敏感资源标识符暴露给用户,例如idorderId
  • 使用不可预测的标识符(如UUID)代替自增ID。

示例:使用UUID代替自增ID

GET /order/details?orderUuid=550e8400-e29b-41d4-a716-446655440000

4. 实现RBAC(基于角色的访问控制)

  • 确保不同角色的用户只能访问各自权限范围内的资源。
  • 在权限验证逻辑中检查资源的所有权和角色限制。

示例:订单权限校验

if (!order.getOwner().equals(currentUser) && !currentUserRole.equals("ADMIN")) {
  throw new AccessDeniedException("权限不足!");
}

5. 隐藏或限制前端可见信息

  • 避免在前端暴露不必要的敏感数据。
  • 使用后端分页和查询接口限制返回的资源范围。

6. 使用安全框架

  • 利用Spring Security、Shiro等框架提供的访问控制功能,减少手动检查逻辑的遗漏风险。

Spring Security 示例

@PreAuthorize("hasRole('USER') and #order.owner == authentication.name")
public Order getOrderDetails(@RequestParam int orderId) {
    return orderService.getOrderById(orderId);
}

总结

水平越权的特点

  • 攻击者与目标用户的权限级别相同。
  • 通过篡改请求访问本不属于自己的资源。

核心防护措施

  1. 后端验证资源的归属关系。
  2. 使用不可预测的标识符(如UUID)。
  3. 最小化前端传递的敏感参数。
  4. 实施RBAC权限管理。
  5. 利用安全框架提供的访问控制功能。

通过以上措施,可以有效防止水平越权攻击,保护系统的资源安全。