【问题标题】:Security cookie_secure CSRF not working安全 cookie_secure CSRF 不起作用
【发布时间】:2015-04-04 03:38:56
【问题描述】:

我目前正在使用 Codeigniter,并希望在 config.php 中启用:

$config['cookie_secure']    = TRUE; 

我也在用:

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = '***';
$config['csrf_cookie_name'] = '***';
$config['csrf_expire'] = 7200;

连接仅是 https。但是当我使用 cookie_secure 选项时,CSRF 不再工作并给出:

The action you have requested is not allowed.

由于这种措施,Codeigniter 无法将 CSRF 存储在 cookie 中。我该如何解决?我喜欢同时使用这两种安全措施。

<form action="<?php echo base_url().'login/'; ?>" method="post">

  <?php echo form_hidden($this->security->get_csrf_token_name(), $this->security->get_csrf_hash()); ?>

【问题讨论】:

  • 您使用的是什么版本的 CI?
  • 另外,你真的有*** 作为你的令牌名称吗?我假设不是,但请在那里举个例子。
  • 你在使用表单助手吗?
  • 版本 2.2.2 并且名称 = hg4dr3356H
  • 检查 [this][1] 链接。您在网站上使用 https 协议吗? [1]:stackoverflow.com/questions/21214612/…

标签: php codeigniter cookies csrf


【解决方案1】:

看起来这可以解决问题,请确保您的代码中有form_open()。根据documentation on codeigniter form helper,

创建一个带有基本 URL 的开始表单标签...

这也应该在没有form_hidden()的情况下自动添加csrf。

【讨论】:

    【解决方案2】:

    当我将 cookie_secure 设置为 truecsrf_protection 设置为 true 时,我遇到了同样的问题。

    我首先注意到的是没有设置 CSRF cookie。

    查看/system/core/Security.php中的csrf_set_cookie()函数,你会看到:

    /**
     * Set Cross Site Request Forgery Protection Cookie
     *
     * @return  object
     */
    public function csrf_set_cookie()
    {
        $expire = time() + $this->_csrf_expire;
        $secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
    
        if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off'))
        {
            return FALSE;
        }
    
        setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
    
        log_message('debug', "CRSF cookie Set");
    
        return $this;
    }
    

    不过,和大多数人一样,我使用负载平衡器来终止 SSL。各个服务器不知道流量是通过 HTTPS 传输的,因为流量是通过内部网络上的端口 80 发送到每个服务器的。这就是HTTP_X_FORWARDED_PROTO 的用途。

    我最终覆盖了/application/core/MY_Security.php 中的csrf_set_cookie() 来解决这个问题:

    /**
     * Set Cross Site Request Forgery Protection Cookie
     *
     * @return  object
     */
    public function csrf_set_cookie()
    {
        $expire = time() + $this->_csrf_expire;
        $secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
    
        if (
            $secure_cookie &&
            (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off') &&
            (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] != 'https')
        ) {
            return FALSE;
        }
    
        setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
    
        log_message('debug', "CRSF cookie Set");
    
        return $this;
    }
    

    【讨论】:

      【解决方案3】:

      如果你想解决这个CODEIGNITER BUG,你可以设置如下:

      $config['sess_cookie_name'] = 'ci_projectname_session';
      

      ...

      ...

      $config['cookie_prefix']    = 'ci_projectname_';
      

      如上例,cookie 前缀和 cookie 名称必须以相同开头。

      【讨论】:

        猜你喜欢
        • 2011-06-22
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        相关资源
        最近更新 更多