什么是PHP的session.referer_check保护我?

时间:2011-02-01 14:46:24

标签: php security cakephp

我正在使用CakePHP制作一个需要相当安全的系统,因为我们处理的是钱,客户的账户等等。到目前为止,一切都很好,直到我必须与支付平台集成我需要重定向到他们的网站,他们重定向回我的网站。

这在我的开发机器(debug = 2)中工作正常,但在生产中,当客户被重定向回来时,他会得到一个登录提示,而不是回到他的“登录区域”。经过大量挖掘后,我发现这是因为CakePHP设置了session.referer_check,如果HTTP_REFERER来自另一个主机,则会使会话无效。

现在,通常情况下,我会毫不犹豫地禁用它,但在这个系统中,我更关注安全性而不是正常情况。

我的问题是session.referer_check究竟应该保护我什么? 如果我将其关闭,我的网站可以进行什么样的攻击/利用/坏事?

我猜这里存在一些原因,但我无法想象它会保护我什么。

你可以给我任何想法吗? 是否安全禁用此功能?

谢谢你 丹尼尔

3 个答案:

答案 0 :(得分:23)

这是为Session Fixation和CSRF / XSRF提供有限保护。检查引用者是a valid method of stopping xsrf。阻止会话固定的更好方法是Session.use_only_cookies,因为黑客无法在受害者浏览器上为他尚未控制的域设置cookie。

但是,Session.referer_check 很容易绕过。它只是在referer域中查找子字符串。如果子字符串一起丢失,如果原始URL是https://则会发生这种情况,那么会话ID将无效。但是,如果它是一个子字符串而不是一个完整的字符串,那么你可以通过引用www.somedomain.com来绕过www.somedomain.com.some_hacker.com。简而言之,我认为这是完全没用的

答案 1 :(得分:4)

请记住,基本上所有的referer_check都在做:

$pattern = "/^http:\/\/www\.myurl\.com(\/.*)*$/";

if(!empty($_SERVER['HTTP_REFERER']) && !preg_match($pattern, $_SERVER['HTTP_REFERER'])) {
   session_destroy();
}

令人讨厌的是referer_check中内置的PHP不会接受一系列网址,但您可以自己创建自己的网址。

因此,对于CakePHP,您可以执行以下操作:

// ADD THIS TO /app/config/config.php
$config['CustomSecurity'] = array(
    'accept_referers' => array(
        'http://www.my_site.com',
        'https://www.other_allowed_referer.com',
    )
);

// ADD THIS TO /app/app_controller.php

private function referer_check(){
   if(!empty($_SERVER['HTTP_REFERER'])) {
      $accept_referers = Configure::read('CustomSecurity.accept_referers');
      $referer_accepted = false;
      foreach($accept_referers as $referer) {
         $pattern =  '/^'.preg_replace('/(\.|\/)/','\\\$1',$referer).'(\/.*)*$/';
         if(preg_match($pattern, $_SERVER['HTTP_REFERER'])) 
            $referer_accepted = true;
      }
      if(!$referer_accepted) {
         $this->Session->destroy();
         exit;
      }
   }        
}

和你的app_controller::before_filter功能,来电:

$this->referer_check();
无论如何......或类似的东西......对于代码格式化感到抱歉,textarea是一个小问题:)

答案 2 :(得分:3)

以这种方式检查引用可以帮助防止Cross-site request forgery

理想情况下,您需要一种方法让引用者检查匹配您自己的域或支付平台的域,但因为它是一个简单的子串检查而不是模式匹配我不认为这是可能的

如果您禁用此功能,则应采取其他措施来防止此类攻击。