如何防止PHP中的CRLF注入(Http响应分裂)

时间:2015-07-09 12:54:19

标签: php security cakephp newline httpresponse

我在PHP中预防CRLF注射做了R& D,但我没有在我的案例中找到任何解决方案,因为我使用burp suite工具使用CRLF字符注入一些标题,如下所示。

// Using my tool i put CRLF characters at the start of my request url 
GET /%0d%0a%20HackedHeader:By_Hacker controller/action

//This generates an header for me like below
HackedHeader:By_Hacker

所以我可以像上面那样修改所有标题

这个工具就像一个代理服务器,因此它捕获请求并给出响应,我们可以按照我们想要的方式修改响应。

所以我只是通过使用CRLF字符注入一些头来修改响应。现在,服务器通过在响应中注入CRLF字符来响应此请求。

我只是担心像Pragma,Cache-Control,Last-Modified这样的标题字段会导致缓存中毒攻击。

标头和setcookie包含针对响应/标头拆分的缓解,但这些不能支持我修复上述问题

修改

当我向mysite.com请求时,请联系我们以下页面这是我在我的工具中捕获的请求,如下所示

Request headers:
GET /contactus HTTP/1.1
Host: mysite.com
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

我得到了上述请求的响应HTML

现在,对于使用该工具的相同请求,我将添加自定义标题,如下所示

Request Headers:
GET /%0d%0a%20Hacked_header:By_Hacker/contactus HTTP/1.1
Host: mysite.com
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

Response Headers:
HTTP/1.1 302 Found
Date: Fri, 10 Jul 2015 11:51:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Fri, 10 Jul 2015 11:51:22 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Location: mysite.com
 Hacked_header:By_Hacker/..
Vary: Accept-Encoding
Content-Length: 2
Keep-Alive: timeout=5, max=120
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

您可以在上面的回复中看到注入的标题 Hacked_header:By_Hacker /..

无论如何在php或apache服务器配置中都有防止这种类型的标题'劈吗

1 个答案:

答案 0 :(得分:3)

不确定为什么所有下来的选票 - 事实上,这是一个有趣的问题:)

我可以看到你已经标记了CakePHP - 这意味着你的应用程序正在使用Cake Framework ...非常好!如果您使用的是Cake 3,它会自动剥离:%0d%0a

或者,如果您收到回复标题,只需剥离%0d%0a,您就可以了!

可以应用这些内容 - 第三方API响应或者说...... Webhook响应!或者处理完全处理国际化的方法。例如:lang = en到lang = fr其中GET参数直接设置为响应标题...这不是明智之举!

理想情况下,回复将为GET而不是标题,但无论如何只是删除%0d%0a并且你很好。

回答您的修改。

You can see the injected header Hacked_header:By_Hacker/.. in the above response

无法控制或停止注入标头,交配。我们无法控制其他服务器的功能。

问题是..你如何处理响应标题?

答案是...... 您清理它 ,因为ndm表示您需要清理输入。你得到一个响应是一个输入。一旦检测到%0d%0a,就会丢弃响应。

需要代码工作吗?

<?php
$cr = '/\%0d/';
$lf = '/\%0a/';

$response = // whatever your response is generated in;
$cr_check = preg_match($cr , $response);
$lf_check = preg_match($lf , $response);

if (($cr_check > 0) || ($lf_check > 0)){
    throw new \Exception('CRLF detected');
}