background image

 

$_SESSION

['HTTP_USER_AGENT'] = md5(

$_SERVER

['HTTP_USER_AGENT']);

}
 
?>
 
我观察过,在某些版本的

IE 浏览器中,用户正常访问一个网页和刷新一个网页时发出的

Accept 头部信息不同,因此 Accept 头部不能用来判断一致性。
确保

User-Agent 头部信息一致的确是有效的,但如果会话标识通过 cookie 传递(推荐方

式),有道理认为,如果攻击者能取得会话标识,他同时也能取得其它

HTTP 头部。由于

cookie 暴露与浏览器漏洞或跨站脚本漏洞相关,受害者需要访问攻击者的网站并暴露所有
头部信息。所有攻击者要做的只是重建头部以防止任何对头部信息一致性的检查。
比较好的方法是产生在

URL 中传递一个标记,可以认为这是第二种验证的形式(虽然更

弱)。使用这个方法需要进行一些编程工作,

PHP 中没有相应的功能。例如,假设标记保存

$token

中,你需要把它包含在所有你的应用的内部链接中:

代码如下

:

<?php

$url

 = 

array

();

$html

 = 

array

();

$url

['token'] = rawurlencode(

$token

);

$html

['token'] = htmlentities(

$url

['token'], ENT_QUOTES, 'UTF-8');

?>
 
<a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>
 
为了更方便地管理这个传递过程,你可能会把整个请求串放在一个变量中。你可以把这个变
量附加到所有链接后面,这样即便你一开始没有使用该技巧,今后还是可以很方便地对你
的代码作出变化。
该标记需要包含不可预测的内容,即便是在攻击者知道了受害者浏览器发出的

HTTP 头部

的全部信息也不行。一种方法是生成一个随机串作为标记:
代码如下

:

<?php

$string

 = 

$_SERVER

['HTTP_USER_AGENT'];

$string

 .= 'SHIFLETT';

$token

 = md5(

$string

);

$_SESSION

['token'] = 

$token

;

?>
 
当你使用随机串时(如

SHIFLETT),对它进行预测是不现实的。此时,捕获标记将比预测

标记更为方便,通过在

URL 中传递标记和在 cookie 中传递会话标识,攻击时需要同时抓取

它们二者。这样除非攻击者能够察看受害者发往你的应用所有的

HTTP 请求原始信息才可以,

因为在这种情况下所有内容都暴露了。这种攻击方式实现起来非常困难(所以很罕见),要
防止它需要使用

SSL。

有专家警告不要依赖于检查

User-Agent 的一致性。这是因为服务器群集中的 HTTP 代理服务

器会对

User-Agent 进行编辑,而本群集中的多个代理服务器在编辑该值时可能会不一致。如