C# 应用程序漏洞速查指南(下)

336 阅读9分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情

书接上文

我将在这篇文章中介绍的漏洞是:

  • 敏感数据泄露或信息泄露
  • 认证绕过
  • 访问控制不当
  • 目录遍历或路径遍历
  • 任意文件写入
  • 拒绝服务攻击 (DoS)
  • 加密漏洞
  • 不安全的 TLS 配置和不正确的证书验证
  • 批量分配
  • 打开重定向
  • 跨站请求伪造 (CSRF)
  • 服务器端请求伪造 (SSRF)
  • 违反信任边界

敏感数据泄露

当应用程序未能正确保护敏感信息时,就会发生敏感数据泄漏,使用户能够访问他们不应该访问的信息。这些敏感信息可能包括有助于攻击的技术细节,例如软件版本号、内部 IP 地址、敏感文件名和文件路径。它还可能包含允许攻击者对应用程序进行源代码审查的源代码。有时,该应用程序会泄露用户的私人信息,例如他们的银行帐号、电子邮件地址和邮寄地址。

应用程序可以泄露敏感技术细节的一些常见方式是通过描述性响应标头、带有堆栈跟踪或数据库错误消息的描述性错误消息、系统文件系统上的打开目录列表,以及在 HTML 和模板文件中显示注释。

身份验证绕过

身份验证是指在执行敏感操作或访问敏感数据之前证明一个人的身份。如果在应用程序上未正确实施身份验证,攻击者可以利用这些错误配置来访问他们不应该访问的功能。

访问控制不当

身份验证绕过问题本质上是访问控制不当。当应用程序中的访问控制实施不当并且可以被攻击者绕过时,任何时候都会发生不当的访问控制。然而,访问控制不仅仅包括身份验证。身份验证要求用户证明他们的身份(“你是谁?”),而授权则要求应用程序:“允许该用户做什么?” 适当的身份验证和授权共同确保用户无法访问超出其权限的功能。

有几种配置用户授权的方法:基于角色的访问控制、基于所有权的访问控制、访问控制列表等。

目录遍历

目录遍历漏洞是另一种不适当的访问控制。当攻击者可以通过操纵用户输入字段中的文件路径来查看、修改或执行他们不应该访问的文件时,就会发生这种情况。此过程涉及通过向文件路径添加 ../ 字符或其他特殊字符来操纵应用程序用来引用文件的文件路径变量。../ 序列在 Unix 系统中是指当前目录的父目录,因此将其添加到文件路径中,通常可以访问到 web 目录之外的系统文件。

攻击者通常可以使用目录遍历来访问敏感文件,如配置文件、日志文件和源代码。为防止目录遍历,应该验证插入文件路径的用户输入或避免直接引用文件名并改用间接标识符。

任意文件写入

任意文件写入漏洞的工作原理与目录遍历类似。如果应用程序将文件写入底层机器并通过用户输入确定输出文件名,攻击者可能能够在他们想要的任何路径上创建任意文件或覆盖现有系统文件。攻击者可能能够更改密码文件或日志文件等关键系统文件,或将他们自己的可执行文件添加到脚本目录中。

减轻这种风险的最佳方法是不根据任何用户输入创建文件名,包括会话信息、HTTP 输入或用户控制的任何内容。你应该控制每个创建的文件的文件名、路径和扩展名。例如,可以在每次用户需要生成唯一文件时生成一个随机的字母数字文件名。还可以在创建文件之前删除用户输入的特殊字符。

拒绝服务攻击

拒绝服务攻击或 DoS 攻击会破坏目标机器,使合法用户无法访问其服务。攻击者可以通过耗尽服务器的所有资源、崩溃进程或一次发出过多耗时的 HTTP 请求来发起 DoS 攻击。

拒绝服务攻击很难防御,但有一些方法可以通过让攻击者尽可能困难来最大限度地降低风险。例如,你可以部署提供 DoS 保护的防火墙,并通过设置文件大小限制和禁止某些文件类型来防止基于逻辑的 DoS 攻击。

加密漏洞

加密问题可能是应用程序中可能发生的最严重的漏洞之一。加密漏洞是指未正确实施加密和散列的情况。这可能导致数据泄漏和通过会话欺骗绕过身份验证。

开发人员在网站上实施加密时常犯的一些错误是:

  • 使用弱算法
  • 使用错误的算法
  • 创建自定义算法
  • 生成弱随机数
  • 将编码误认为是加密

不安全的 TLS 配置和不正确的证书验证

除了正确加密数据存储中的信息外,你还需要确保你正在与受信任的机器而不是恶意的第三方进行通信。TLS 使用数字证书作为其公钥加密的基础,你需要在与第三方建立连接之前验证这些证书。应该验证尝试连接的服务器是否具有由受信任的证书颁发机构 (CA) 颁发的证书,并且证书链中的所有证书都没有过期。

批量分配

“批量赋值”是指一次为多个变量或对象属性赋值的做法。当应用程序自动将用户输入分配给多个程序变量或对象时,就会发生批量分配漏洞。这是许多旨在简化应用程序开发的应用程序框架中的一项功能。

但是,此功能有时允许攻击者随意覆盖、修改或创建新的程序变量或对象属性。这可能导致绕过身份验证和操纵程序逻辑。为防止批量分配,可以使用你正在使用的框架禁用批量分配功能,或使用白名单仅允许对某些属性或变量进行分配。

开放的重定向

网站通常需要自动重定向其用户。例如,当未经身份验证的用户尝试访问需要登录的页面时,就会发生这种情况。网站通常会将这些用户重定向到登录页面,然后在他们通过身份验证后将他们返回到原来的位置。

在开放重定向攻击期间,攻击者通过向用户提供重定向到其他地方的合法站点的 URL 来诱骗用户访问外部站点。这可以让用户相信他们仍在原来的网站上,并帮助诈骗者建立更可信的网络钓鱼活动。

为防止打开重定向,需要确保应用程序不会将用户重定向到恶意位置。例如,可以通过验证重定向 URL 来完全禁止站外重定向。还有许多其他方法可以防止打开重定向,例如检查请求的引荐来源网址或使用页面索引进行重定向。但是,由于难以验证 URL,开放式重定向仍然是现代 Web 应用程序中的普遍问题。

跨站请求伪造

跨站点请求伪造 (CSRF) 是一种客户端技术,用于攻击 Web 应用程序的其他用户。使用 CSRF,攻击者可以发送假装来自受害者的 HTTP 请求,代表受害者执行不需要的操作。例如,攻击者可以在未经许可的情况下更改密码或从银行帐户转账。

与开放重定向不同,有一种万无一失的方法可以防止 CSRF:使用 CSRF 令牌和 SameSite cookie 的组合,并避免使用 GET 请求进行状态更改操作。

服务器端请求伪造

SSRF,即服务器端请求伪造,是一种当攻击者能够代表服务器发送请求时发生的漏洞。它允许攻击者“伪造”易受攻击服务器的请求签名,从而在网络上占据特权位置,绕过防火墙控制,并获得对内部服务的访问权限。

根据授予易受攻击服务器的权限,攻击者可能能够读取敏感文件、进行内部 API 调用以及访问内部服务(如隐藏的管理面板)。防止 SSRF 漏洞的最简单方法是永远不要根据用户输入发出出站请求。如果确实需要根据用户输入发出出站请求,则需要在发起请求之前验证这些地址。

违反信任边界

“信任边界”是指不受信任的用户输入进入受控环境的地方。例如,一个 HTTP 请求在被服务器验证之前被认为是不受信任的输入。

存储、传输和处理可信和不可信输入的方式应该有明确的区别。当不尊重这种区别并且可信和不可信数据相互混淆时,就会发生信任边界违规。例如,如果受信任和不受信任的数据存储在相同的数据结构或数据库中,应用程序将开始混淆两者。在这种情况下,不受信任的数据可能会被错误地视为已验证。

防止违反信任边界的一个好方法是在验证之前永远不要将不受信任的输入写入会话存储。