跳过内容

C1:实施访问控制

描述

访问控制(或授权)是允许或拒绝来自用户、程序或进程的特定请求。在每次访问控制决策中,给定主体请求访问给定对象。访问控制是考虑已定义策略并确定给定主体是否被允许访问给定对象的过程。

访问控制还涉及授予和撤销这些权限的行为。

访问控制通常应用于多个层面,例如,对于具有数据库后端应用程序,它既适用于业务逻辑层面,也适用于数据库行层面。此外,应用程序可以提供多种执行操作的方式(例如,通过 API 或网站)。所有这些不同的层面和访问路径必须保持一致,即使用相同的访问控制检查,以防止安全漏洞。

授权(验证对特定功能或资源的访问)不等同于身份验证(验证身份)。

威胁

  • 攻击者可以利用配置宽松的访问控制策略来访问组织不打算公开的数据。
  • 攻击者可能会发现应用程序中存在多个访问控制组件,并利用其中最薄弱的一个。
  • 管理员可能会忘记停用旧账户,而攻击者可能会发现该账户并利用其访问数据。
  • 攻击者可能会获得数据访问权限,该数据的策略在最后一步允许访问。(缺乏默认拒绝)

实施

以下是应用程序开发初始阶段应考虑的最低限度的访问控制设计要求。

1) 提前彻底设计访问控制

一旦选择了特定的访问控制设计模式,在应用程序中重新设计新的访问控制模式通常会非常困难且耗时。访问控制是应用程序安全设计的主要领域之一,必须在前期进行彻底设计,尤其是在解决多租户和水平(依赖数据)访问控制等需求时。

应考虑两种核心类型的访问控制设计。

  • 基于角色的访问控制 (RBAC) 是一种用于控制资源访问的模型,其中资源上的允许操作与角色而非单个主体身份相关联。
  • 基于属性的访问控制 (ABAC) 将根据用户的任意属性、对象的任意属性以及可能被全局识别且与当前策略更相关的环境条件来授予或拒绝用户访问。访问控制设计可能一开始很简单,但通常会变得复杂且功能繁多。在评估软件框架的访问控制能力时,请确保您的访问控制功能能够根据您的特定访问控制功能需求进行定制。

2) 强制所有访问请求都经过访问控制检查

确保所有访问请求都必须通过访问控制验证层。Java 过滤器或其他自动请求处理机制等技术是理想的编程组件,它们将确保所有请求都经过访问控制检查。这在 RFC 2904 中被称为 策略执行点

3) 整合访问控制检查

使用单一的访问控制程序或例程。这可以防止出现拥有多个访问控制实现的情况,其中大多数是正确的,但有些存在缺陷。通过采用集中式方法,您可以将安全资源集中于审查和修复执行访问控制检查的单个中心库或函数,然后在整个代码库和组织中重复使用它。

4) 默认拒绝

确保默认情况下所有请求都被拒绝,除非它们被明确允许。这还包括访问缺少访问控制的 API(REST 或 Webhooks)。此规则在应用程序代码中体现的方式有很多种。一些示例如下:

  1. 应用程序代码在处理访问控制请求时可能会抛出错误或异常。在这种情况下,访问控制应始终被拒绝。

  2. 当管理员创建新用户或用户注册新账户时,该账户默认应具有最小或没有访问权限,直到该访问权限被配置。

  3. 当应用程序中添加新功能时,应禁止所有用户使用它,直到其被正确配置。

5) 最小权限原则 / 及时 (JIT),仅需访问 (JEA)

实施该原则的一个例子是为每个需要高权限活动的组织职能创建专用的特权角色和账户,并避免日常使用完全特权的“admin”角色/账户。

为了进一步提高安全性,您可以实施即时 (JIT) 或仅需访问 (JEA):确保所有用户、程序或进程仅获得足以完成当前任务的访问权限。这种访问应在主体发出请求时及时提供,并且访问权限应在短时间内授予。请警惕那些不提供细粒度访问控制配置功能的系统。

6) 不要硬编码角色

许多应用程序框架默认使用基于角色的访问控制。在应用程序代码中发现这种性质的检查是很常见的。

if (user.hasRole("ADMIN")) || (user.hasRole("MANAGER")) {
    deleteAccount();
}

请谨慎对待代码中这种类型的基于角色的编程。它具有以下局限性或危险:

  • 这种性质的基于角色的编程是脆弱的。很容易在代码中创建不正确或缺失的角色检查。
  • 硬编码的角色不允许多租户。要使基于角色的系统对不同的客户有不同的规则,将需要极端的措施,例如分支代码或为每个客户添加检查。
  • 包含许多访问控制检查的大型代码库可能难以审计或验证整体应用程序访问控制策略。
  • 硬编码的角色在审计期间被发现时,也可能被视为后门。

7) ABAC 策略执行点示例

请考虑使用以下编程方法来设置访问控制强制点

if (user.hasPermission("DELETE_ACCOUNT")) {
    deleteAccount();
}

这种性质的基于属性或功能的访问控制检查是构建设计良好且功能丰富的访问控制系统的起点。这种编程类型还允许随着时间的推移实现更大的访问控制定制能力。

防止的漏洞

参考资料

工具