常见的认证和授权漏洞(及其避免方法

Sven Morgenroth在保罗的安全周播第720期

在保罗的安全周播网络安全播客中,Invicti安全研究员SvenMorgenroth讨论了网络应用中安全身份验证和授权的众多挑战,并结合实际示例展示了真实的漏洞。请观看完整访谈,并继续阅读有关认证和授权安全的概述。

关键要点

在现代网络应用中,安全认证和授权是保护敏感数据的核心。这包括身份验证—证明您身份的过程;以及授权—检查您是否具有访问特定资源权限的过程。本文将讨论常见的身份验证和授权漏洞及其相关的最佳实践。

身份验证与授权……有什么区别?

身份验证和授权这两个概念虽然看似相似,但实际上各自有明确的定义:

  • 身份验证 是指证明您的身份。这可能意味着输入用户名和密码、通过单点登录(SSO)流程登录,或者提供独特的访问密钥。

  • 授权 是指检查您是否具有相应的权限。一旦您被认证,应用程序将验证您是否可以访问特定资源或操作,通常基于您在应用中的角色。

由于它们通常一起执行,并且常常一起出现问题,身份验证和授权合起来有时被简单称为“auth”,这也是发音更简单和输入更快。现代企业网络应用在正确实施访问控制以保护敏感数据方面面临越来越大的挑战,因此,相关的漏洞和攻击在网络安全领域至关重要。

身份验证出错 – 常见漏洞类型

有效且全面的访问控制的实施始终是一个挑战,许多因素使其变得更加复杂。安全性往往在软件开发过程中被忽视,实施访问控制也不例外。为了更容易、更快速的开发,整个应用可能在没有任何访问限制的情况下构建,随后在最后一步才添加登录表单,这增加了与身份验证相关的安全风险。

分布式软件架构将身份验证挑战提升到了一个全新的层面,请求往往穿越多个服务和接口。确保在不同上下文中进行适当的访问控制极具挑战性,尤其在开发模块由不同团队负责的情况下。当需要跨API、数据格式、源和物理系统传递身份认证信息时,身份验证相关的漏洞为何如此常见也就不言而喻了。以下是一些典型示例,许多在此博客中有详细讨论。

不安全的值比较

首先是语言特定的不安全值比较,通常称为类型混淆漏洞。JavaScript和PHP是两种流行的网络开发语言,它们都是松散类型的语言,这意味着默认情况下,它们对数据类型的接受非常宽松。这两种语言在值比较时也各自有不同的怪癖,因此如果没有对给予足够的关注,攻击者可能能够输入一个在特定上下文下总是被接受的特殊值。

想象一下,您有一个登录表单,其中用户名和密码值直接发送到一个脆弱的PHP脚本,该脚本使用 ==
操作符进行典型的松散比较。正如中详细解释的那样,使用此操作符比较任何字符串与TRUE或0时,默认将返回TRUE。因此在最简单的情况下,仅仅在JSON登录请求中发送布尔TRUE就可能足以绕过身份验证。

使用 ===
操作符进行严格比较或使用专用的比较函数通常能够避免这类漏洞,但在大型软件项目中,即使是看似微不足道的错误有时也可能进入生产环境。有关的更多信息,请参见我们之前的帖子。

基于路径的身份验证陷阱

另一种可能导致身份验证绕过攻击的不当做法是通过检查特定路径来实现访问控制。例如,一个应用程序可能会通过将用户请求的路径与管理面板的路径进行比较来检查用户是否有权访问管理面板。没有输入清理,攻击者可通过插入目录遍历字符串来请求看似不同(因此未被阻止)的路径,最终却指向相同

Leave a Reply

Your email address will not be published. Required fields are marked *