目录
漏洞简介
CRLF是”回车 + 换行”(\r\n)的简称。在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP 内容并显示出来。所以,一旦能够控制HTTP 消息头中的字符,注入一些恶意的换行,这样就能注入一些会话Cookie或者HTML代码,所以CRLF Injection又叫HTTP Response Splitting,简称HRS。HRS是比XSS危害更大的安全问题。
形成原理
在HTTP协议中,HTTP头是通过”\r\n”来分隔的。因此如果服务端没有过滤”\r\n”,而又把用户输入的数据放在HTTP头中,则有可能导致安全隐患。
PHP
<?php
header('Location : test' . $user_data);
...
Java
String author = request.getParameter(AUTHOR_PARAM);
...
Cookie cookie = new Cookie("author", author);
cookie.setMaxAge(cookieExpiration);
response.addCookie(cookie);
影响范围
- CRLF常被用做不同语义之间的分隔符。因此通过”注入CRLF字符”,就有可能改变原有的语义,达到误导用户的目的。
利用方式
这个例子通过CRLF注入完成了一次XSS攻击。在参数中插入CRLF字符:
<form id="x" action="http://login.u51.com/login.do?email=a%0d%0a%0d%0a<script>alert(/xss/);</script>" method="post">
<input name="password" value="testtest">
...
</form>
服务端返回:
HTTP/1.1 200 OK
Server: nginx
Set-Cookie: _de=a
<script>alert(/xss/);</script>; domain=.u51.com; expires=Thu, 10-Dec-2017 GMT
...
注意到服务器返回时,在Set-Cookie的值里插入了两次”\r\n”换行符。而两次”\r\n”意味着HTTP头的结束,在两次CRLF之后跟着的是HTTP Body。攻击者在两次CRLF之后构造了恶意的HTML脚本,从而得以执行,XSS攻击成功。
修复方案
- 过滤”%0d%0a”;
- 对需要set到HTTP响应头的输入、输出进行URL-encode处理。