Posted by D Blog on November 9, 2023

参考: The Web Application Hacker’s Handbook Chapter 8

访问控制是Web应用程序安全性最容易理解的领域之一,尽管您在实施它们时必须谨慎地采用消息灵通,透彻的方法。

首先,您应该避免几个明显的陷阱。 这些通常是由于对有效访问控制的基本要求不了解或对用户将要提出的请求种类以及应用程序需要针对其进行自我辩护的错误假设所致:

  • 不要依赖用户对应用程序URL的无知或用于指定应用程序资源(例如帐号和文档ID)的标识符。 假设用户知道每个应用程序的URL和标识符,并确保仅应用程序的访问控制就足以防止未经授权的访问。
  • 不要信任任何用户提交的参数来表示访问权限(例如admin = true)。
  • 不要假设用户将按预期顺序访问应用程序页面。 不要假设由于用户无法访问“编辑用户”页面,所以他们无法访问与其链接的“编辑用户X”页面。
  • 不要相信用户不要篡改通过客户端传输的任何数据。 如果某些用户提交的数据已经过验证,然后通过客户端传输,则在不重新验证的情况下不要依赖于重新传输的值。

以下是在Web应用程序中实施有效访问控制的最佳实践方法:

  • 以下是在Web应用程序中实施有效访问控制的最佳实践方法:
  • 根据用户会话制定所有访问控制决定。
  • 使用中央应用程序组件检查访问控制。
  • 通过该组件处理每个客户端请求,以验证发出请求的用户是否被允许访问所请求的功能和资源。
  • 使用编程技术来确保上一点没有例外。 一种有效的方法是强制每个应用程序页面必须实现由中央访问控制机制查询的接口。 如果您强迫开发人员在每个页面中明确地编写访问控制逻辑代码,那么就没有任何遗漏的借口。
  • 对于特别敏感的功能(例如管理页面),您可以进一步限制IP地址的访问,以确保只有特定网络范围内的用户才能访问该功能,而无论其登录状态如何。
  • 如果需要保护静态内容,则有两种提供访问控制的方法。 首先,可以通过将文件名传递给实现相关访问控制逻辑的动态服务器端页面来间接访问静态文件。 其次,可以使用HTTP身份验证或应用程序服务器的其他功能来控制对静态文件的直接访问,以包装传入的请求并在授予访问权限之前检查资源的权限。
  • 指定用户要访问的资源的标识符在通过客户端传输时很容易受到篡改。 服务器应仅信任服务器端数据的完整性。 每当通过客户端传输这些标识符时,都需要重新验证它们,以确保授权用户访问所请求的资源。
  • 对于安全性至关重要的应用程序功能(例如在银行应用程序中创建新的帐单收款人),请考虑实施每笔交易重新认证和双重授权,以进一步确保该功能不会被未授权方使用。 这也减轻了其他可能攻击的后果,例如会话劫持。
  • 记录访问敏感数据或执行敏感操作的每个事件。 这些日志将使潜在的访问控制漏洞得以检测和调查。

Web应用程序开发人员通常会偶尔实现访问控制功能。 他们在需要某些访问控制的情况下将代码添加到各个页面,并且经常在页面之间剪切和粘贴相同的代码以实现类似的要求。 这种方法在产生的访问控制机制中存在缺陷的固有风险。 在需要控件的情况下,许多情况被忽略了,针对一个区域设计的控件可能无法在另一区域中按预期方式运行,并且在应用程序内其他地方进行的修改可能会违反现有控件的假设,从而破坏现有控件。

与这种方法相比,前面描述的使用中央应用程序组件强制执行访问控制的方法具有许多优点:

  • 它提高了应用程序中访问控制的清晰度,使不同的开发人员可以快速了解其他人实施的控件。
  • 它使可维护性更加有效和可靠。 大多数更改只需要对单个共享组件应用一次,而无需剪切和粘贴到多个位置。
  • 它提高了适应性。 如果出现新的访问控制要求,则可以轻松地将其反映在每个应用程序页面实现的现有API中。
  • 与在整个应用程序中逐行实施访问控制代码相比,它所导致的错误和遗漏更少。

多层特权模型(A Multilayered Privilege Model)

与访问有关的问题不仅适用于Web应用程序本身,还适用于Web应用程序下的其他基础结构层,尤其是应用程序服务器,数据库和操作系统。 采用深度防御方法来实现安全性需要在每一层实施访问控制以创建多层保护。 这样就可以更好地保证防止未经授权的访问,因为如果攻击者成功破坏了一层防御,则攻击可能仍会被另一层防御所阻止。

如前所述,除了在Web应用程序本身中实现有效的访问控制外,还可以通过多种方式对应用程序基础的组件应用多层方法:

  • 应用服务器可以根据在应用服务器层定义的用户角色来控制对整个URL路径的访问。
  • 当执行不同用户的操作时,应用程序可以使用不同的数据库帐户。 对于只应查询数据(而不更新数据)的用户,应使用具有只读特权的帐户。
  • 可以使用特权表在数据库本身内实现对不同数据库表的访问的细粒度控制。
  • 可以将用于运行基础结构中每个组件的操作系统帐户限制为该组件实际需要的功能最弱的特权。

在一个复杂的,对安全性至关重要的应用程序中,可以借助一个矩阵来设计这种分层防御,该矩阵定义了应用程序内的不同用户角色和应分配给每个角色的每一层的不同特权。 图8-6是复杂应用程序特权矩阵的部分示例。

figure8-6

在这种安全模型中,您可以看到如何应用各种有用的访问控制概念:

  • 程序控制—各个数据库特权的矩阵存储在数据库内的表中,并以编程方式应用于执行访问控制决策。 用户角色的分类为应用某些访问控制检查提供了快捷方式,并且也可以通过编程方式应用。 程序控制的粒度非常细,可以在应用程序中执行访问控制决策的过程中构建任意复杂的逻辑。
  • 任意访问控制(DAC)-管理员可以使用任意访问控制,将与他们拥有的特定资源相关的特权委派给其他用户。 这是一个封闭的DAC模型,其中除非明确授予访问权限,否则拒绝访问。 管理员还可以锁定或终止单个用户帐户。 这是一个开放式DAC模型,除非明确撤回,否则允许访问。 各种应用程序用户都有创建用户帐户的特权,再次应用了自由访问控制。
  • 基于角色的访问控制(RBAC)-命名角色包含不同的特定特权集,并且每个用户都被分配了其中一个角色。 这是分配和执行不同权限的快捷方式,对于帮助管理复杂应用程序中的访问控制是必需的。 使用角色对用户请求执行前期访问检查可以使许多未经授权的请求迅速被拒绝,同时执行的处理量最少。 此方法的一个示例是保护特定类型的用户可以访问的URL路径。

在设计基于角色的访问控制机制时,必须平衡角色的数量,以便它们仍然是帮助管理应用程序中权限的有用工具。 如果创建了太多细粒度的角色,那么不同角色的数量将变得很笨拙,并且很难准确地进行管理。 如果创建的角色太少,则产生的角色将是用于管理访问的粗略工具。 可能会为单个用户分配执行其功能并非绝对必要的特权。

如果平台级控件用于基于HTTP方法和URL限制对不同应用程序角色的访问,则应使用默认拒绝模型来设计这些控件,这是防火墙规则的最佳实践。 这应该包括将特定的HTTP方法和URL分配给特定角色的各种特定规则,并且最终规则应拒绝任何与先前规则不匹配的请求。

  • 声明式控制-应用程序在访问数据库时使用受限的数据库帐户。 它为不同的用户组使用不同的帐户,每个帐户具有执行允许该组执行的操作所需的最低特权级别。 这种声明性控件是从应用程序外部声明的。 这是深度防御原则的有用应用程序,因为特权是由不同的组件赋予应用程序的。 即使用户找到一种方法来破坏在应用程序层内实现的访问控制以执行敏感操作(例如添加新用户),也无法这样做。 他正在使用的数据库帐户在数据库中没有必需的特权。

通过应用程序部署期间应用的部署描述符文件,在应用程序服务器级别存在一种应用声明式访问控制的不同方法。 但是,这些可能是相对较钝的工具,而且在大型应用程序中无法始终很好地扩展以管理细粒度的特权。

HACK STEPS
如果您要攻击使用这种多层特权模型的应用程序,则很可能会防御许多在应用访问控制中通常犯的最明显的错误。 您可能会发现,由于在其他层进行了适当的保护,因此规避应用程序内实现的控件不会使您走得太远。 考虑到这一点,您仍然可以使用几种潜在的攻击路线。 最重要的是,了解每种控件类型的局限性(就其不提供的保护而言)将帮助您确定最有可能影响它的漏洞:

  • 应用程序层内的程序检查可能容易受到基于注入的攻击。
  • 在应用服务器层定义的角色通常被粗略定义,并且可能不完整。
  • 在使用低特权操作系统帐户运行应用程序组件的地方,它们通常可以读取主机文件系统中的多种潜在敏感数据。 即使仅读取敏感数据,授予任意文件访问权限的任何漏洞也可能会被有用地利用。
  • 应用服务器软件本身的漏洞通常使您能够击败在应用层内实现的所有访问控制,但是您对数据库和操作系统的访问仍然可能有限。
  • 在正确位置的单个可利用访问控制漏洞仍可能为严重的特权升级提供起点。 例如,如果您发现一种修改与帐户关联的角色的方法,则可能会发现再次使用该帐户登录可以在应用程序层和数据库层上提供增强的访问权限。

Summary

访问控制缺陷可以通过多种方式表现出来。 在某些情况下,它们可能没有意思,从而允许非法访问无害功能,而该功能无法再用于进一步提升特权。 在其他情况下,发现访问控制中的弱点可能很快导致应用程序完全受损。

访问控制中的缺陷可能来自多种来源。 不良的应用程序设计可能使检查未经授权的访问变得困难或变得不可能,简单的监督可能只会使一个或两个功能受到保护,或者关于用户行为方式的有缺陷的假设会在违反这些假设时使应用程序不受保护。

在许多情况下,发现访问控制中断几乎是微不足道的。 您只需请求一个公共管理URL即可直接访问该功能。 在其他情况下,这可能会非常困难,并且细微的缺陷可能会潜伏在应用程序逻辑内部,特别是在复杂的高安全性应用程序中。 攻击访问控制时,最重要的教训是四处查看。 如果您在努力取得进展,请耐心等待并测试每个应用程序功能的每个步骤。 允许您拥有整个应用程序的bug即将来临。

Chapter 8 Attacking Access Controls(2)-Attacking Access Controls(2)

: