开发安全之:Header Manipulation

Overview

方法 echo_json() 包含未验证的数据, 这会招致各种形式的攻击,包括:cache-poisoning、cross-site scripting、cross-user defacement、page hijacking、cookie manipulation 或 open redirect。

Details

以下情况中会出现 Header Manipulation 漏洞:

  1. 数据通过一个不可信赖的数据源进入 Web 应用程序,最常见的是 HTTP 请求。

  2. 数据包含在一个 HTTP 响应头文件里,未经验证就发送给了 Web 用户。 在这种情况下,数据通过 header() 传送。 如同许多软件安全漏洞一样,Header Manipulation 只是通向终端的一个途径,它本身并不是终端。从本质上看,这些漏洞是显而易见的:一个攻击者将恶意数据传送到易受攻击的应用程序,且该应用程序将数据包含在 HTTP 响应头文件中。 其中最常见的一种 Header Manipulation 攻击是 HTTP Response Splitting。为了成功地实施 HTTP Response Splitting 盗取,应用程序必须允许将那些包含 CR(回车,由 %0d 或 \r 指定)和 LF(换行,由 %0a 或 \n 指定)的字符输入到头文件中。

攻击者利用这些字符不仅可以控制应用程序要发送的响应剩余头文件和正文,还可以创建完全受其控制的其他响应。 如今的许多现代应用程序服务器可以防止 HTTP 头文件感染恶意字符。例如,当新行传递到 header() 函数时,最新版本的 PHP 将生成一个警告并停止创建头文件。如果您的 PHP 版本能够阻止设置带有换行符的头文件,则其具备对 HTTP Response Splitting 的防御能力。然而,单纯地过滤换行符可能无法保证应用程序不受 Cookie Manipulation 或 Open Redirects 的攻击,因此必须在设置带有用户输入的 HTTP 头文件时采取措施。

示例: 下段代码会从 HTTP 请求读取位置,并在 HTTP 响应的位置字段的头文件中对其进行设置。

<?php $location = $_GET['some_location']; ... header("location: $location"); ?>

假设在请求中提交了一个由标准字母数字字符组成的字符串,如"index.html",则包含该 Cookie 的 HTTP 响应可能表现为以下形式: HTTP/1.1 200 OK ... location: index.html ... 然而,因为该位置的值由未经验证的用户输入组成,所以仅当提交给 some_location 的值不包含任何 CR 和 LF 字符时,响应才会保留这种形式。如果攻击者提交的是一个恶意字符串,比如"index.html\r\nHTTP/1.1 200 OK\r\n...",那么 HTTP 响应就会被分割成以下形式的两个响应: HTTP/1.1 200 OK ... location: index.html HTTP/1.1 200 OK ... 显然,第二个响应已完全由攻击者控制,攻击者可以用任何所需标头和正文内容构建该响应。攻击者可以构建任意 HTTP 响应,从而发起多种形式的攻击,包括:cross-user defacement、web and browser cache poisoning、cross-site scripting 和 page hijacking。

**Cross-User Defacement:**攻击者可以向一个易受攻击的服务器发出一个请求,导致服务器创建两个响应,其中第二个响应可能会被曲解为对其他请求的响应,而这一请求很可能是与服务器共享相同 TCP 连接的另一用户发出的。这种攻击可以通过以下方式实现:攻击者诱骗用户,让他们自己提交恶意请求;或在远程情况下,攻击者与用户共享同一个连接到服务器(如共享代理服务器)的 TCP 连接。最理想的情况是,攻击者通过这种方式使用户相信自己的应用程序已经遭受了黑客攻击,进而对应用程序的安全性失去信心。最糟糕的情况是,攻击者可能提供经特殊技术处理的内容,这些内容旨在模仿应用程序的执行方式,但会重定向用户的私人信息(如帐号和密码),将这些信息发送给攻击者。

Cache Poisoning: 如果多用户 Web 缓存或者单用户浏览器缓存将恶意构建的响应缓存起来,该响应的破坏力会更大。如果响应缓存在共享的 Web 缓存(如在代理服务器中常见的缓存)中,那么使用该缓存的所有用户都会不断收到恶意内容,直到清除该缓存项为止。同样,如果响应缓存在单个用户的浏览器中,那么在清除该缓存项以前,该用户会不断收到恶意内容。然而,影响仅局限于本地浏览器的用户。

**Cross-Site Scripting:**一旦攻击者控制了应用程序传送的响应,就可以选择多种恶意内容并将其传播给用户。Cross-Site Scripting 是最常见的攻击形式,这种攻击在响应中包含了恶意的 JavaScript 或其他代码,并在用户的浏览器中执行。基于 XSS 的攻击手段花样百出,几乎是无穷无尽的,但通常它们都会包含传输给攻击者的私有数据(如 Cookie 或者其他会话信息)。在攻击者的控制下,指引受害者进入恶意的网络内容;或者利用易受攻击的站点,对用户的机器进行其他恶意操作。对于易受攻击的应用程序用户,最常见且最危险的攻击就是使用 JavaScript 将会话和身份验证信息返回给攻击者,而后攻击者就可以完全控制受害者的帐号了。

**Page Hijacking:**除了利用一个易受攻击的应用程序向用户传输恶意内容,还可以利用相同的根漏洞,将服务器生成的供用户使用的敏感内容重定向,转而供攻击者使用。攻击者通过提交一个会导致两个响应的请求,即服务器做出的预期响应和攻击者创建的响应,致使某个中间节点(如共享的代理服务器)误导服务器所生成的响应,将本来应传送给用户的响应错误地传给攻击者。因为攻击者创建的请求产生了两个响应,第一个被解析为针对攻击者请求做出的响应,第二个则被忽略。当用户通过同一 TCP 连接发出合法请求时,攻击者的请求已经在此处等候,并被解析为针对受害者这一请求的响应。这时,攻击者将第二个请求发送给服务器,代理服务器利用针对受害者(用户)的、由该服务器产生的这一请求对服务器做出响应,因此,针对受害者的这一响应中会包含所有头文件或正文中的敏感信息。

**Cookie Manipulation:**当与类似跨站请求伪造的攻击相结合时,攻击者就可以篡改、添加、甚至覆盖合法用户的 cookie。

**Open Redirect:**如果允许未验证的输入来控制重定向机制所使用的 URL,可能会有利于攻击者发动钓鱼攻击。

Recommendations

防止 Header Manipulation 漏洞的解决方法是,确保在适当位置进行输入验证并检验其属性是否正确。 由于 Header Manipulation 漏洞出现在应用程序的输出中包含恶意数据时,因此,合乎逻辑的做法是在应用程序输出数据前一刻对其进行验证。然而,由于 Web 应用程序常常会包含复杂而难以理解的代码,用以生成动态响应,因此,这一方法容易产生遗漏错误(遗漏验证)。

降低这一风险的有效途径是对 Header Manipulation 也执行输入验证。 由于 Web 应用程序必须验证输入信息以避免出现其他漏洞(如 SQL Injection),因此,一种相对简单的解决方法是增强应用程序现有的输入验证机制,增加针对 Header Manipulation 的检查。尽管具有一定的价值,但 Header Manipulation 输入验证并不能取代严格的输出验证。应用程序可能通过共享的数据存储器或其他可信赖的数据源接受输入,而该数据存储器所接受的输入源可能并未执行适当的输入验证。因此,应用程序不能间接地依赖于该数据或其他任意数据的安全性。这就意味着,避免 Header Manipulation 漏洞的最佳方法是验证所有应用程序输入数据或向用户输出的数据。

针对 Header Manipulation 漏洞进行验证最安全的方式是创建一份安全字符允许列表,允许其中的字符出现在 HTTP 响应标头中,并且只接受完全由这些经认可的字符组成的输入。例如,有效的用户名可能仅包含字母数字字符,帐号可能仅包含 0-9 的数字。

更灵活的方法是执行拒绝列表,但其安全性较差,该列表会在使用输入之前有选择地拒绝或避免潜在的危险字符。为了创建这样的列表,首先需要了解在 HTTP 响应头文件中具有特殊含义的一组字符。尽管 CR 和 LF 字符是 HTTP Response Splitting 攻击的核心,但其他字符,如":"(冒号)和 '='(等号),在响应标头中同样具有特殊的含义。 在应用程序中确定针对 Header Manipulation 攻击执行验证的正确要点,以及验证过程中要考虑的特殊字符之后,下一个难点就是确定验证过程中处理各种特殊字符的方式。

应用程序应拒绝任何要添加到 HTTP 响应头文件中的包含特殊字符的输入,这些特殊字符(特别是 CR 和 LF)是无效字符。 许多应用程序服务器都试图避免应用程序出现 HTTP Response Splitting 漏洞,其做法是为负责设置 HTTP 标头和 Cookie 的函数提供各种实现方式,以检验是否存在进行 HTTP Response Splitting 攻击必需的字符。

不要依赖运行应用程序的服务器,以此确保该应用程序的安全。对于任何已开发的应用程序,并不能保证在其生命周期中它会在哪些应用程序服务器中运行。由于标准和已知盗取方式的演变,我们不能保证应用程序服务器将继续保持同步。

相关推荐
jjyangyou2 小时前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
AltmanChan3 小时前
大语言模型安全威胁
人工智能·安全·语言模型
马船长3 小时前
红帆OA iorepsavexml.aspx文件上传漏洞
安全
hikktn10 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
23zhgjx-NanKon12 小时前
华为eNSP:QinQ
网络·安全·华为
23zhgjx-NanKon12 小时前
华为eNSP:mux-vlan
网络·安全·华为
昔我往昔12 小时前
阿里云文本内容安全处理
安全·阿里云·云计算
棱角~~15 小时前
盘点和嗨格式一样好用的10款数据恢复!!
数据库·经验分享·安全·电脑·学习方法
NETFARMER运营坛16 小时前
如何优化 B2B 转化率?这些步骤你不可不知
大数据·安全·阿里云·ai·ai写作
安徽京准16 小时前
京准时钟:无人机卫星信号安全防护隔离装置
安全·无人机·信号安全防护装置·卫星安全隔离装置·北斗授时安全隔离·北斗对时防护隔离装置