日期:2014-05-17  浏览次数:20391 次

CI框架源码阅读---------Security.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

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

/**
 * Security Class
 * 本类包含一些方法,能帮助您创建安全的应用程序,对输入的数据进行安全方面的处理。
 * CI官方手册本类的地址:http://codeigniter.org.cn/user_guide/libraries/security.html
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Security
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/libraries/security.html
 */
class CI_Security {

	/**
	 * Random Hash for protecting URLs
	 * 为保护URL(跨站脚本攻击)的随机hash值
	 * @var string
	 * @access protected
	 */
	protected $_xss_hash			= '';
	/**
	 * Random Hash for Cross Site Request Forgery Protection Cookie
	 * 防止跨站请求伪造cookie的随机hash
	 * @var string
	 * @access protected
	 */
	protected $_csrf_hash			= '';
	/**
	 * Expiration time for Cross Site Request Forgery Protection Cookie
	 * Defaults to two hours (in seconds)
	 * 跨站请求保护Cookie的过期时间,默认是2小时(单位秒)
	 * @var int
	 * @access protected
	 */
	protected $_csrf_expire			= 7200;
	/**
	 * Token name for Cross Site Request Forgery 伪造 Protection Cookie
	 * 跨站请求伪造保护的Cookie令牌名
	 * @var string
	 * @access protected
	 */
	protected $_csrf_token_name		= 'ci_csrf_token';
	/**
	 * Cookie name for Cross Site Request Forgery Protection Cookie
	 * 跨站请求伪造保护的Cookie的Cookie名
	 * @var string
	 * @access protected
	 */
	protected $_csrf_cookie_name	= 'ci_csrf_token';
	/**
	 * List of never allowed strings
	 * 决不允许的字符串的列表
	 * @var array
	 * @access protected
	 */
	protected $_never_allowed_str = array(
		'document.cookie'	=> '[removed]',
		'document.write'	=> '[removed]',
		'.parentNode'		=> '[removed]',
		'.innerHTML'		=> '[removed]',
		'window.location'	=> '[removed]',
		'-moz-binding'		=> '[removed]',
		'<!--'				=> '<!--',
		'-->'				=> '-->',
		'<![CDATA['			=> '<![CDATA[',
		'<comment>'			=> '<comment>'
	);

	/* never allowed, regex replacement */
	/**
	 * List of never allowed regex replacement
	 * 不允许的正则替换字符串列表
	 * @var array
	 * @access protected
	 */
	protected $_never_allowed_regex = array(
		'javascript\s*:',
		'expression\s*(\(|&\#40;)', // CSS and IE
		'vbscript\s*:', // IE, surprise!
		'Redirect\s+302',
		"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
	);

	/**
	 * Constructor
	 *
	 * @return	void
	 */
	public function __construct()
	{
		// Is CSRF protection enabled?
		// csrf 是否开启 
		if (config_item('csrf_protection') === TRUE)
		{
			// CSRF config 读取CSRF 配置并赋值给本类下的对应的属性
			foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key)
			{
				if (FALSE !== ($val = config_item($key)))
				{
					$this->{'_'.$key} = $val;
				}
			}

			// Append application specific cookie prefix
			// 添加应用指定的cookie前缀
			if (config_item('cookie_prefix'))
			{
				$this->_csrf_cookie_name = config_item('cookie_prefix').$this->_csrf_cookie_name;
			}

			// Set the CSRF hash
			// 设置CSRF hash
			$this->_csrf_set_hash();
		}

		log_message('debug', "Security Class Initialized");
	}

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

	/**
	 * Verify Cross Site Request Forgery Protection
	 * 验证跨站请求伪造保护
	 * @return	object
	 */
	public function csrf_verify()
	{
		// If it's not a POST request we will set the CSRF cookie
		// 如果不是post请求我们要设置 CSRF cookie
		if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
		{
			return $this->csrf_set_cookie();
		}

		// Do the tokens exist in both the _POST and _COOKIE arrays?
		// 如果请求令牌不存在,调用csrf_show_error 报错
		if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cook