温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

CI的CSRF的改造

发布时间:2020-09-13 12:33:51 来源:网络 阅读:625 作者:dfwasds 栏目:web开发

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>密&nbsp;&nbsp;码:</td>                     <td class="width260"><input type="password" class="text" name="password"></td>                     <td colspan="2">&nbsp;</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>


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI