php ci csrf,CI的CSRF的改造

CI的CSRF是有缺陷的。

只要同时开俩个不同的涉及csrf的页面,

http://host/csrf1

http://host/csrf2

就会发现页面直接互相影响(问题1)。

即使同一页面也涉及这样的问题。

http://host/csrf1

http://host/csrf1

也会发现这样的问题(问题2)。

先解决简单问题2

只需要将配置 csrf_regenerate 设置为 false; 即是cookie过期或者被清掉。$config['csrf_regenerate'] = FALSE;

解决复杂问题1:

一. 将system/core/Input 中的 验证代码过滤。// CSRF Protection check

if ($this->_enable_csrf === TRUE && ! is_cli())

{

//$this->security->csrf_verify();

}

二. 改造Security类class CI_Security {

/**

* Class constructor

*

* @returnvoid

*/

public function __construct()

{

$this->charset = strtoupper(config_item('charset'));

log_message('info', 'Security Class Initialized');

}

public function start_csrf($class, $function)

{

// Is CSRF protection enabled?

if (config_item('csrf_protection'))

{

if(!$class || !$function){

return ;

}

$this->_csrf_cookie_name = md5($class.'_'.$function);

// CSRF config

foreach (array(

'csrf_expire',

'csrf_token_name',

//'csrf_cookie_name',

) as $key)

{

if (NULL !== ($val = config_item($key)))

{

$this->{'_'.$key} = $val;

}

}

// Append application specific cookie prefix

if ($cookie_prefix = config_item('cookie_prefix'))

{

//$this->_csrf_cookie_name = $cookie_prefix.$this->_csrf_cookie_name;

}

// Set the CSRF hash

$this->_csrf_set_hash();

$this->csrf_set_cookie();

}

}

// --------------------------------------------------------------------

/**

* CSRF Verify

*

* @returnCI_Security

*/

public function csrf_verify($class, $function)

{

if (!config_item('csrf_protection')){

return ;

}

if(!$class || !$function){

return ;

}

$this->_csrf_cookie_name = md5($class.'_'.$function);

// CSRF config

foreach (array(

'csrf_expire',

'csrf_token_name',

//'csrf_cookie_name',

) as $key)

{

if (NULL !== ($val = config_item($key)))

{

$this->{'_'.$key} = $val;

}

}

// If it's not a POST request we will set the CSRF cookie

if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')

{

//return $this->csrf_set_cookie();

$this->csrf_show_error();

}

// Check if URI has been whitelisted from CSRF checks

if ($exclude_uris = config_item('csrf_exclude_uris'))

{

$uri = load_class('URI', 'core');

foreach ($exclude_uris as $excluded)

{

if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), $uri->uri_string()))

{

return $this;

}

}

}

// Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate

$valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])

&& hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]);

// We kill this since we're done and we don't want to pollute the _POST array

unset($_POST[$this->_csrf_token_name]);

// Regenerate on every submission?

if (config_item('csrf_regenerate'))

{

// Nothing should last forever

unset($_COOKIE[$this->_csrf_cookie_name]);

$this->_csrf_hash = NULL;

}

$this->_csrf_set_hash();

$this->csrf_set_cookie();

if ($valid !== TRUE)

{

$this->csrf_show_error();

}

log_message('info', 'CSRF token verified');

return $this;

}

// --------------------------------------------------------------------

/**

* CSRF Set Cookie

*

* @codeCoverageIgnore

* @returnCI_Security

*/

public function csrf_set_cookie()

{

if (!config_item('csrf_protection')){

return ;

}

$expire = time() + $this->_csrf_expire;

$secure_cookie = (bool) config_item('cookie_secure');

if ($secure_cookie && ! is_https())

{

return FALSE;

}

setcookie(

$this->_csrf_cookie_name,

$this->_csrf_hash,

$expire,

config_item('cookie_path'),

config_item('cookie_domain'),

$secure_cookie,

config_item('cookie_httponly')

);

log_message('info', 'CSRF cookie sent');

return $this;

}

// --------------------------------------------------------------------

/**

* Set CSRF Hash and Cookie

*

* @returnstring

*/

protected function _csrf_set_hash()

{

if (!config_item('csrf_protection')){

return ;

}

if ($this->_csrf_hash === NULL)

{

// If the cookie exists we will use its value.

// We don't necessarily want to regenerate it with

// each page load since a page could contain embedded

// sub-pages causing this feature to fail

if (isset($_COOKIE[$this->_csrf_cookie_name]) && is_string($_COOKIE[$this->_csrf_cookie_name])

&& preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1)

{

return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];

}

$rand = $this->get_random_bytes(16);

$this->_csrf_hash = ($rand === FALSE)

? md5(uniqid(mt_rand(), TRUE))

: bin2hex($rand);

}

return $this->_csrf_hash;

}

}

三.使用实例

controller<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends CI_Controller {

public function csrf_test1()

{

if($_POST){

$this->security->csrf_verify(__CLASS__, __FUNCTION__);

var_dump($_POST);

exit;

}

$this->security->start_csrf(__CLASS__, __FUNCTION__);

$csrf = array(

'name' => $this->security->get_csrf_token_name(),

'hash' => $this->security->get_csrf_hash()

);

$data['csrf'] = $csrf;

$this->load->view('csrf1', $data);

}

}

view<?php

defined('BASEPATH') OR exit('No direct script access allowed');

?>

html>

Welcome to CodeIgniter

::selection { background-color: #E13300; color: white; }

::-moz-selection { background-color: #E13300; color: white; }

body {

background-color: #fff;

margin: 40px;

font: 13px/20px normal Helvetica, Arial, sans-serif;

color: #4F5155;

}

a {

color: #003399;

background-color: transparent;

font-weight: normal;

}

h1 {

color: #444;

background-color: transparent;

border-bottom: 1px solid #D0D0D0;

font-size: 19px;

font-weight: normal;

margin: 0 0 14px 0;

padding: 14px 15px 10px 15px;

}

code {

font-family: Consolas, Monaco, Courier New, Courier, monospace;

font-size: 12px;

background-color: #f9f9f9;

border: 1px solid #D0D0D0;

color: #002166;

display: block;

margin: 14px 0 14px 0;

padding: 12px 10px 12px 10px;

}

#body {

margin: 0 15px 0 15px;

}

p.footer {

text-align: right;

font-size: 11px;

border-top: 1px solid #D0D0D0;

line-height: 32px;

padding: 0 10px 0 10px;

margin: 20px 0 0 0;

}

#container {

margin: 10px;

border: 1px solid #D0D0D0;

box-shadow: 0 0 8px #D0D0D0;

}

Welcome to CodeIgniter!

用户名:
密  码: 
 

" value="=$csrf['hash'];?>" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值