CI的CSRF是有缺陷的。
創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比進賢網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式進賢網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋進賢地區(qū)。費用合理售后完善,十年實體公司更值得信賴。
只要同時開倆個不同的涉及csrf的頁面,
http://host/csrf1
http://host/csrf2
就會發(fā)現(xiàn)頁面直接互相影響(問題1)。
?即使同一頁面也涉及這樣的問題。
http://host/csrf1
http://host/csrf1
也會發(fā)現(xiàn)這樣的問題(問題2)。
先解決簡單問題2
只需要將配置 csrf_regenerate 設(shè)置為 false; 即是cookie過期或者被清掉。
$config['csrf_regenerate']?=?FALSE;
解決復(fù)雜問題1:
一. 將system/core/Input 中的 驗證代碼過濾。?
//?CSRF?Protection?check if?($this->_enable_csrf?===?TRUE?&&?!?is_cli()) { ???//$this->security->csrf_verify(); }
二. 改造Security類
class?CI_Security?{ /** ?*?Class?constructor ?* ?*?@return void ?*/ 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 ?* ?*?@return CI_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 ?*?@return CI_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 ?* ?*?@return string ?*/ 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
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
???? ????Welcome?to?CodeIgniter ????????Welcome?to?CodeIgniter!
???????????? ????