什么是访问控制?
访问控制(或授权)是对谁(或什么)可以执行尝试的操作或访问他们所请求的资源的约束条件的应用。在Web应用程序的上下文中,访问控制取决于身份验证和会话管理:
- 身份验证可以识别用户并确认他们就是他们所说的身份。
- 会话管理标识该同一用户正在发出哪些后续HTTP请求。
- 访问控制确定是否允许用户执行他们尝试执行的操作。
访问控制是一个经常遇到且通常很关键的安全漏洞。访问控制的设计和管理是一个复杂而动态的问题,将业务,组织和法律约束应用于技术实施。访问控制设计决策必须由人决定,而不是技术,而且潜在的错误可能性很高。
从用户的角度来看,访问控制可以分为以下几类:
- 垂直访问控制
- 水平访问控制
- 上下文相关的访问控制
垂直访问控制
垂直访问控制是一种机制,用于限制对其他类型的用户不可用的敏感功能的访问。
使用垂直访问控制,不同类型的用户可以访问不同的应用程序功能。例如,管理员可能能够修改或删除任何用户的帐户,而普通用户无权访问这些操作。垂直访问控制可以是安全模型的更细粒度的实现,这些模型旨在执行业务策略,例如职责分离和最低特权。
水平访问控制
水平访问控制是一种机制,用于将资源的访问限制为专门允许访问这些资源的用户。
使用水平访问控制,不同的用户可以访问相同类型的资源的子集。例如,银行业务应用程序将允许用户查看交易并从自己的帐户进行付款,但不能查看其他任何用户的帐户。
上下文相关的访问控制
依赖于上下文的访问控制根据应用程序的状态或用户与应用程序的交互来限制对功能和资源的访问。
上下文相关的访问控制可防止用户以错误的顺序执行操作。例如,零售网站可能会阻止用户在付款后修改购物车中的内容。
访问控制示例
当用户实际上可以访问某些资源或执行某些他们不应该访问的资源时,存在损坏的访问控制漏洞。
纵向特权升级
如果用户可以访问他们被禁止访问的功能,那么这就是垂直特权升级。例如,如果非管理用户实际上可以访问可以删除用户帐户的管理页面,则这是垂直特权升级。
未受保护的功能
在最基本的情况下,如果应用程序不对敏感功能实施任何保护,则会出现垂直特权升级。例如,管理功能可能是从管理员的欢迎页面链接的,而不是从用户的欢迎页面链接的。但是,用户可能直接通过直接浏览到相关的管理URL就能访问管理功能。
例如,一个网站可能在以下URL上托管敏感功能:
https://insecure-website.com/admin
实际上,任何用户都可以访问此目录,不仅是在其用户界面中具有指向该功能链接的管理用户。在某些情况下,管理URL可能会在其他位置公开,例如robots.txt文件:
https://insecure-website.com/robots.txt
即使未在任何地方公开该URL,攻击者也可以使用单词表来强行执行敏感功能的位置。
在某些情况下,敏感功能并没有得到严格的保护,但是通过给它一个不太可预测的URL来隐藏它:所谓的“默默无闻的安全性”。
但仅隐藏敏感功能无法提供有效的访问控制,因为用户可能仍会以各种方式发现混淆的URL。
攻击者可能无法直接猜测到这一点。但是,该应用程序仍可能会将URL泄露给用户。例如,URL可能会在JavaScript中公开,该JavaScript根据用户的角色构造用户界面:
<script>
var isAdmin = false;
if (isAdmin) {
...
var adminPanelTag = document.createElement('a');
adminPanelTag.setAttribute('https://insecure-website.com/administrator-panel-yb556');
adminPanelTag.innerText = 'Admin panel';
...
}
</script>
如果他们是管理员用户,此脚本将向用户的UI添加链接。但是,包含URL的脚本对于所有用户都是可见的,无论其角色如何。
基于参数的访问控制方法
某些应用程序在登录时确定用户的访问权限或角色,然后将该信息存储在用户可控制的位置,例如隐藏字段,cookie或预设查询字符串参数。该应用程序根据提交的值做出后续的访问控制决策。例如:
https://insecure-website.com/login/home.jsp?admin=true
https://insecure-website.com/login/home.jsp?role=1
这种方法从根本上来说是不安全的,因为用户可以简单地修改值并获得对未经授权的功能(例如管理功能)的访问权限。
平台配置错误导致访问控制中断
某些应用程序通过基于用户角色限制对特定URL和HTTP方法的访问来在平台层实施访问控制。例如,一个应用程序可能配置如下规则:
DENY: POST, /admin/deleteUser, managers
对于该管理者组中的用户, 此规则拒绝POST对URL上的方法的访问/admin/deleteUser。在这种情况下,各种事情都会出错,从而导致访问控制绕过。
某些应用程序框架支持各种非标准HTTP标头,这些标头可用于覆盖原始请求中的URL,例如X-Original-URL和X-Rewrite-URL。如果网站使用严格的前端控件来限制基于URL的访问,但是应用程序允许通过请求标头覆盖URL,则可能可以使用如下请求来绕过访问控制:
POST / HTTP/1.1
X-Original-URL: /admin/deleteUser
...
将请求行中的URL更改为/并添加HTTP标头X-Original-URL: /invalid。观察到该应用程序返回“未找到”响应。这表明后端系统正在处理X-Original-URL标头中的URL 。
将X-Original-URL标头的值更改为/admin。请注意,您现在可以访问管理页面。
要删除用户x,请添加?username=x到实际查询字符串中,然后将X-Original-URL路径更改为/admin/delete。
与请求中使用的HTTP方法有关的替代攻击可能会出现。上面的前端控件基于URL和HTTP方法限制访问。某些网站在执行操作时可以使用其他HTTP请求方法。如果攻击者可以使用GET(或其他)方法对受限URL执行操作,则他们可以绕过在平台层实现的访问控制。
横向特权升级
当用户能够访问属于另一个用户的资源而不是他们自己的那种类型的资源时,就会出现水平特权升级。例如,如果某个员工仅应能够访问自己的工作和工资记录,但实际上也可以访问其他员工的记录,则这就是横向特权提升。
水平特权升级攻击可能使用与垂直特权升级类似的利用方法。例如,用户通常可以使用如下所示的URL访问自己的帐户页面:
https://insecure-website.com/myaccount?id=123
现在,如果攻击者将id参数值修改为另一个用户的参数值,则攻击者可能会访问具有相关数据和功能的另一个用户的帐户页面。
在某些应用程序中,可利用参数没有可预测的值。例如,应用程序可以使用全局唯一标识符(GUID)来代替用户,而不是递增数字。在这里,攻击者可能无法猜测或预测另一个用户的标识符。但是,属于其他用户的GUID可能会在引用用户的应用程序的其他位置公开,例如用户消息或评论。
在某些情况下,应用程序会检测到何时不允许用户访问资源,并将重定向返回到登录页面。但是,包含重定向的响应可能仍然包含属于目标用户的一些敏感数据,因此攻击仍然成功。
水平到垂直特权升级
通常,通过损害特权较高的用户,可以将横向特权升级攻击转变为纵向特权升级。例如,水平升级可能允许攻击者重置或捕获属于另一个用户的密码。如果攻击者以管理员用户为目标并破坏了他们的帐户,则他们可以获得管理员权限,因此可以进行垂直特权升级。
例如,攻击者也许可以使用针对水平特权升级已经描述的参数篡改技术来访问另一个用户的帐户页面:
https://insecure-website.com/myaccount?id=456
如果目标用户是应用程序管理员,则攻击者将获得对管理帐户页面的访问权限。该页面可能会公开管理员的密码或提供更改密码的方法,或者可能提供对特权功能的直接访问。
不安全的直接对象引用
不安全的直接对象引用(IDOR)是访问控制漏洞的子类别。当应用程序使用用户提供的输入直接访问对象并且攻击者可以修改输入以获得未经授权的访问时,就会发生IDOR。尽管它只是许多实现错误的一个例子,并且可能导致访问控制被规避.
多步骤流程中的访问控制漏洞
许多网站通过一系列步骤来实现重要功能。当需要捕获各种输入或选项时,或者当用户需要在执行操作之前查看并确认详细信息时,通常会执行此操作。例如,用于更新用户详细信息的管理功能可能涉及以下步骤:
- 加载表单,其中包含特定用户的详细信息。
- 提交更改。
- 查看更改并确认。
有时,网站将对其中某些步骤实施严格的访问控制,而忽略其他步骤。例如,假设访问控制已正确应用于第一步和第二步,但未正确应用于第三步。实际上,该网站假定用户只有完成了正确控制的第一步后,才可以进入第3步。在这里,攻击者可以跳过前两个步骤并直接使用所需参数提交对第三步的请求,从而获得未经授权的功能访问。
如何防止访问控制漏洞
通常,可以采用深度防御方法并应用以下原则来防止访问控制漏洞:
- 切勿仅依靠混淆来进行访问控制。
- 除非打算公开访问资源,否则默认情况下将拒绝访问。
- 尽可能使用单个应用程序范围的机制来执行访问控制。
- 在代码级别,使开发人员必须声明每个资源允许的访问,并默认拒绝访问。
- 彻底审核和测试访问控制,以确保它们按设计工作。