freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

安全开发之如何更安全的设计授权
2024-08-02 15:11:50

近期研读了很多安全架构的文章,认证、授权、鉴权等很多师傅们也说了很多,包括现在业内层出不穷的数据泄露事件,很多也是由于未授权访问引起的,那么除了做好日常的API管理外,从开发的角度来看,该如何更安全的做好授权功能的开发?

授权可以定义为“验证特定实体是否获批执行请求的动作或服务的过程”(NIST)。它与认证不同,认证是核实实体身份的过程,授权是通过验证后匹配对应权限的过程。一个已经通过认证的用户(可能通过提供用户名和密码)通常无权访问系统中所有的资源和执行所有动作。例如,应用程序可能既有普通用户也有管理员,管理员能够执行普通用户没有权限执行的动作,即使他们已经通过认证。此外,访问资源并不总是需要认证;未认证的用户可能被授权访问某些公共资源,如图片或登录页面等。

权限类的漏洞危害很大,攻击者可能能够读取、创建、修改或删除原本应该受到保护的资源(从而危及它们的机密性、完整性或可用性);但是这些行为的实际影响与被破坏资源的关键性和敏感性相关。因此,成功利用授权缺陷的商业成本可以从非常低到极高不等。在例行通过各类安全测试(渗透、漏扫、专项检查、代码审计等)进行权限类漏洞测试的同时,契合安全开发的思想,从研发视角来看,可以从以下几点考虑:

执行最小权限原则

最小权限,作为一项安全概念,也是安全设计的原则之一,最小权限原则指的是只为用户分配完成工作所必需的最小权限的原则。尽管这一原则最常应用于系统管理,但对软件开发人员也有相关性(毕竟代码是研发来写的)。最小权限必须在横向和纵向上都得到应用。例如,从日常管理进行类比,会计和销售代表可能在组织层级中处于同一级别,但两者都需要访问不同的资源来执行他们的工作。会计可能不应该被授予访问客户数据库的权限,销售代表也不应该能够访问工资数据。同样,销售部门负责人可能需要比他们的下属更高级的权限。

开发人员如何进行最小权限设计?对应角色:架构师、安全设计人员,搭配安全开发流程落地

  • 在设计阶段,确保定义了信任边界。列举将访问系统的用户类型、暴露的资源以及可能对这些资源执行的操作(如读取、写入、更新等)。对于每种用户类型和资源的组合,确定用户(基于角色和/或其他属性)应该能够在该资源上执行哪些操作(如果有)。对于ABAC系统,确保考虑了所有类别的属性。例如,销售可能需要在工作时间从内部网络访问客户数据库,但在非工作时间不行、从外网不行等到。
  • 创建测试以验证在设计阶段制定的权限是否得到正确执行。
  • 在应用程序部署后,定期审查系统中的权限,;即确保当前环境中用户的权限不超过在设计阶段定义的权限。
  • 权限最小化原则需提前嵌入。在SDLC早期仔细规划和实施最小权限成本最低。

默认拒绝访问

即使没有明确的访问控制规则匹配,当一个实体请求访问特定资源时,应用程序也不能保持中立。应用程序必须做出决定,无论是隐式还是显式地,要么拒绝,要么允许请求的访问。访问控制可能会发生错误,特别是当访问需求复杂时,逻辑错误就是一个漏洞;因此,不应完全依赖于明确定义的规则来匹配所有可能的请求。出于安全考虑,应将应用程序配置为默认拒绝访问。

开发人员如何设计默认拒绝访问?对应角色:架构师、安全设计人员,搭配安全开发流程落地

  • 在初始开发期间以及应用程序通过应用程序公开新功能或资源时,都应采取“默认拒绝”的策略。应该能够明确证明为什么授予特定用户或组特定权限,而不是假设访问权限是默默认通过。
  • 尽管某些框架或库本身可能采用默认拒绝策略,但应优先选择显式配置而不是依赖于框架或库的默认设置。第三方代码的逻辑和默认设置可能会随着时间而发展与项目的复杂度,开发人员可能无法完全了解或理解变更对特定项目的影响。

在每个请求上验证权限

无论请求是由脚本、服务器端还是任何其他来源发起,都应正确验证每个请求的权限。执行此类检查使用的技术应进行全局配置,而不是需要单独应用于每个方法或类。从攻防的视角来看,攻击者只需要找到一种方法即可。即使只有一个访问控制检查被“遗漏”,资源的机密性和/或完整性也可能受到威胁。仅在大多数请求上正确验证权限是不够的。

可以帮助开发人员执行这种一致权限检查的特定技术包括:

  • Java/Jakarta EE过滤器,包括Spring Security中的实现
  • Django框架中的中间件
  • .NET Core过滤器
  • Laravel PHP框架中的中间件

针对所选工具和技术的授权逻辑内部自检,必要时实施自定义逻辑

开发人员可以访问大量的库、平台和框架,在提供便利性的同时,复杂的逻辑很容易利用各类库和框架实现,然而,这些框架和库不应被视为解决所有开发问题的快速通道;开发人员有责任安全的使用这些框架。针对授权类漏洞,两个重点点是开发人员配置不当/缺乏配置,以及组件本身中的漏洞。

这里重点说说开源组件治理(供应链安全越来越火了)

  • 创建、维护和遵循检测和响应漏洞组件的流程——开源组件安全管理流程
  • 将Dependency Check等工具纳入SDLC,并考虑订阅来自供应商、NVD或其它相关来源的数据源。
  • 实施深度防御。不要依赖任何单一的框架、库、技术或控制来执行适当的访问控制。

配置不当(或完全缺乏配置)问题

这些组件通常旨在是相对通用的工具,但是在使用时必须通过定制或补充额外的逻辑来满足特定应用程序或环境的独特需求。尤其是安全需求

授权的配置考虑因素包括:

  • 彻底理解、分析构建授权逻辑的技术,无论是通过review、重构都可以帮助开发进授权理解,同时为了满足特定的需求,有些授权逻辑还需要重构或自定义,所以并不是说用了别人的框架和组件就一劳永逸了,而是站在巨人的肩膀上更好的设计最适应的授权逻辑。
  • 不要让任何库、平台或框架的功能指导你的授权需求。相反,应首先确定授权需求,然后根据这些需求分析第三方组件。即需要更好的使用工具,而不是由工具主导
  • 不要依赖默认配置。
  • 做好测试!这点属于是兜底,很重要

相对于RBAC,更倾向于基于特性和属性的访问控制

在软件工程中,广泛使用两种基本的访问控制形式:基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)。从我个人来看,ABAC通常应该优先于RBAC。

RBAC:

RBAC是一种访问控制模型,根据分配给用户的角色授予或拒绝访问权限。权限不是直接分配给实体;而是将权限与角色相关联,实体继承分配给它的任何角色的权限。通常,角色与用户之间的关系可以是多对多的,角色可能是分层的。

ABAC:

与RBAC相比,ABAC可以定义为一种访问控制模型,其中“主体对对象执行操作的请求基于主体分配的属性、对象分配的属性、环境条件以及以这些属性和条件指定的一组策略来授予或拒绝”。在NIST SP 800-162中定义,属性只是可以表示为名称-值对的特性,并分配给主体、对象或环境。工作角色、一天中的时间、项目名称、MAC地址和创建日期只是ABAC实现灵活性的一小部分可能属性示例。

为什么说我觉得ABAC相对于RBAC更安全?

  • 支持细粒度、复杂的布尔逻辑。
  • 在大型项目或存在众多角色时的健壮性。
  • 支持多租户和跨组织请求。
  • 管理的便利性。

确保查找ID即使被猜测或无法篡改也不具有可访问性,搭配的场景就是常见的资源便利类和未授权类漏洞,这个从攻击者的视角挖到过很多漏洞,但是我很难描述,场景如猜到一个ID值并拿到了他的资料,但是这个ID可以遍历,同时以ID做索引不做任何鉴权,导致漏洞,我这里直接给开发答案:

确保查找ID的安全性

  • 尽可能避免向用户暴露标识符。例如,应该能够仅基于当前经过身份验证的用户的身份和属性(例如,通过安全实现的JWT或服务器端会话中包含的信息)检索某些对象,如账户详细信息。
  • 使用OWASP ESAPI等工具实现用户/会话特定的间接引用
  • 对每个请求进行特定对象或功能的访问控制检查。仅仅因为用户可以访问某种类型的对象,并不意味着他们应该能够访问该类型的每一对象。

对静态资源执行授权检查

在保护静态资源时,需考虑:

  • 确保静态资源被纳入访问控制策略。静态资源所需的保护类型必然高度依赖于上下文。对于一些静态资源,完全公开访问可能是完全可以接受的,而其他资源则只能在存在严格限制的用户和环境属性集时才能访问。因此,了解正在考虑的特定资源中暴露的数据类型至关重要。可以考虑建立正式的数据分类方案,并将其纳入应用程序的访问控制逻辑
  • 确保任何用于存储静态资源的基于云的服务都使用供应商提供的配置选项和工具进行安全保护。查阅云供应商的文档(请参阅AWS、Google Cloud和Azure的指导)了解具体实施细节。
  • 尽可能使用与保护应用程序其他资源和功能相同的访问控制逻辑和机制来保护静态资源。

确保在正确的位置执行授权检查

开发人员绝不应依赖客户端访问控制检查。客户端逻辑通常很容易被绕过。访问控制检查必须在服务器端执行,可以通过网关或者后端函数落地

授权检查失败时安全退出

授权检查失败在安全应用程序中是正常现象;因此,开发人员必须计划这类失败并安全地处理它们。具体建议包括:

  • 确保处理所有异常和失败的访问控制检查
  • 集中处理失败访问控制检查的逻辑。
  • 验证异常和授权失败的处理。防止更改返回值被绕过(低端漏洞)

实施适当的日志记录

日志记录在我看来是上线后的兜底;日志记录的建议包括:

  • 规范日志记录格式,记录必备信息
  • 仔细确定要记录的信息量。这应根据特定的应用程序环境和需求来确定。记录过多和过少都可能被视为安全弱点。记录过少可能导致恶意活动未被检测到,大大降低了事故后分析的有效性。记录过多不仅可能过度消耗资源并导致过多的误报,还可能导致敏感数据被不必要地记录。
  • 确保系统之间的时钟和时区同步。在事故响应期间和之后,准确度对于串联攻击的顺序至关重要。
  • 考虑将应用程序日志纳入集中式日志服务器或SIEM。

为授权逻辑创建单元和集成测试用例

单元和集成测试对于验证应用程序是否按预期执行并一致地跨变更执行至关重要。访问控制逻辑的缺陷可能很微妙,特别是当需求复杂时;然而,即使是访问控制中的小逻辑或配置错误,也可能导致严重后果。虽然不能替代专门的安全测试,自动化的单元和集成测试访问控制逻辑可以帮助减少进入生产的安全漏洞的数量。

单元和集成测试应该把我们前面提到的很多安全需求(注意点)全部纳入。例如,是否默认拒绝访问?当访问控制检查失败时,即使在异常条件下,应用程序是否能够安全终止?ABAC策略是否得到正确执行等。

# 系统安全 # 授权 # 安全开发
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录