您好,登錄后才能下訂單哦!
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 ?* ?*?@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
<?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'); ?> <!DOCTYPE?html> <html?lang="en"> <head> ????<meta?charset="utf-8"> ????<title>Welcome?to?CodeIgniter</title> ????<style?type="text/css"> ????????::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; ????????} ????????h2?{ ????????????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; ????????} ????</style> </head> <body> <div?id="container"> ????<h2>Welcome?to?CodeIgniter!</h2> ????<div?id="body"> ????????<form?method="post"?action="/welcome/csrf_test1"> ????????????<table> ????????????????<tbody> ????????????????<tr> ????????????????????<td>用戶名:</td> ????????????????????<td?colspan="3"><input?type="text"?id="user_name"?class="text"?name="username"></td> ????????????????</tr> ????????????????<tr> ????????????????????<td>密 碼:</td> ????????????????????<td?class="width260"><input?type="password"?class="text"?name="password"></td> ????????????????????<td?colspan="2"> </td> ????????????????</tr> ????????????????<tr> ????????????????????<th?colspan="4">?<input?class="btnenter"?type="submit"> ????????????????????????<input?type="hidden"?name="<?=$csrf['name'];?>"?value="<?=$csrf['hash'];?>"?/> ????????????????</tr> ????????????????</tbody> ????????????</table> ????????</form> ????</div> </div> </body> </html>
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。