C1:实施访问控制
描述
访问控制(或授权)是允许或拒绝来自用户、程序或进程的特定请求。在每次访问控制决策中,一个给定的主体请求访问一个给定的对象。访问控制是考虑已定义策略并确定给定主体是否被允许访问给定对象的过程。
访问控制也涉及授予和撤销这些权限的行为。
访问控制通常应用于多个层面,例如,对于一个具有数据库后端的应用程序,它既应用于业务逻辑层面,也应用于数据库行层面。此外,应用程序可以提供多种执行操作的方式(例如,通过API或网站)。所有这些不同的层面和访问路径必须保持一致,即使用相同的访问控制检查,以防范安全漏洞。
授权(验证对特定功能或资源的访问)与认证(验证身份)不等同。
威胁
- 攻击者可以利用配置宽松的访问控制策略来访问组织不打算公开的数据。
- 攻击者可能会发现应用程序中的多个访问控制组件,并利用其中最薄弱的一个。
- 管理员可能会忘记注销旧账户,攻击者可能会发现该账户并利用它来访问数据。
- 攻击者可能会获取到那些策略最终允许访问的数据。(缺乏默认拒绝机制)
实施
以下是在应用程序开发初始阶段应考虑的最低访问控制设计要求。
1) 提前彻底设计访问控制
一旦您选择了特定的访问控制设计模式,要用新模式重新设计应用程序中的访问控制通常会很困难且耗时。访问控制是应用程序安全设计中必须预先彻底设计的主要领域之一,特别是在处理多租户和横向(数据依赖)访问控制等需求时。
应考虑两种核心类型的访问控制设计。
- 基于角色的访问控制 (RBAC) 是一种用于控制资源访问的模型,其中资源上的允许操作与角色而非单个主体身份相关联。
- 基于属性的访问控制(ABAC)将根据用户和对象的任意属性以及可能被全局识别且与当前策略更相关的环境条件来授予或拒绝用户访问。访问控制设计可能一开始很简单,但常常会变得复杂且功能繁重。在评估软件框架的访问控制能力时,请确保您的访问控制功能能够根据您特定的访问控制功能需求进行定制。
2) 强制所有访问请求通过访问控制检查
确保所有访问请求都强制通过访问控制验证层。诸如Java过滤器或其他自动请求处理机制之类的技术是理想的编程组件,它们将确保所有请求都经过访问控制检查。这在 RFC 2904 中被称为 策略实施点。
3) 整合访问控制检查
使用单一的访问控制程序或例程。这可以防止出现多个访问控制实现(其中大多数正确,但有些存在缺陷)的情况。通过采用集中式方法,您可以将安全资源集中于审查和修复一个执行访问控制检查的中央库或函数,然后在您的整个代码库和组织中重用它。
4) 默认拒绝
确保默认情况下所有请求都被拒绝,除非它们被明确允许。这也包括访问缺少访问控制的API(REST或webhook)。这条规则在应用程序代码中有多种体现方式。例如:
-
应用程序代码在处理访问控制请求时可能会抛出错误或异常。在这些情况下,访问控制应始终被拒绝。
-
当管理员创建新用户或用户注册新账户时,该账户默认应具有最小或没有访问权限,直到该访问权限被配置。
-
当向应用程序添加新功能时,所有用户都应被禁止使用它,直到其正确配置为止。
5) 最小权限原则 / 即时(JIT)、恰好够用访问(JEA)
实施该原则的一个例子是为每个需要高权限活动的组织功能创建专用的特权角色和账户,并避免使用日常完全特权的“admin”角色/账户。
为了进一步提高安全性,您可以实施即时(JIT)或恰好够用访问(JEA):确保所有用户、程序或进程仅获得足以完成其当前任务的访问权限。此访问权限应在主体发出请求时即时提供,并且权限应仅授予很短的时间。警惕不提供精细访问控制配置能力的系统。
6) 不要硬编码角色
许多应用程序框架默认采用基于角色的访问控制。应用程序代码中常见此类检查。
在代码中编写此类基于角色的编程要小心。它具有以下局限性或危险:
- 这种性质的基于角色的编程是脆弱的。在代码中创建不正确或缺失的角色检查很容易。
- 硬编码角色不允许多租户。需要采取极端措施,例如分叉代码或为每个客户添加检查,才能使基于角色的系统对不同客户拥有不同的规则。
- 包含大量访问控制检查的大型代码库会使审计或验证整体应用程序访问控制策略变得困难。
- 硬编码角色在审计时被发现也可能被视为后门。
7) 基于属性的访问控制(ABAC)策略实施点示例
请考虑使用以下编程方法来实施访问控制:
这种性质的基于属性或功能的访问控制检查是构建设计良好且功能丰富的访问控制系统的起点。这种编程类型还允许随着时间的推移实现更大的访问控制定制能力。
防止的漏洞
参考资料
- OWASP 速查表:授权速查表
- OWASP 速查表:日志记录速查表
- OWASP 速查表:不安全直接对象引用预防速查表
- OWASP ASVS V4 访问控制
- OWASP 测试指南:授权测试
- OAuth2.0 授权协议
- OAuth2.1 草案
- RFC 2904 中的策略实施