Core File (Security class) Security. php

Source: Internet
Author: User
The CI security class provides global protection against CSRF attacks and XSS attacks. you only need to enable it in the configuration file: $ config ['csrf _ protection '] = TRUE; $ config ['global _ xss_fi

The CI security class provides global protection against CSRF attacks and XSS attacks. you only need to enable it in the configuration file:
$ Config ['csrf _ protection '] = TRUE;
$ Config ['global _ xss_filtering '] = TRUE;
And provides practical methods:
$ This-> security-> xss_clean ($ data); // The second parameter is TRUE to verify Image security.
$ This-> security-> sanitize_filename () // filter file names
CI also provides security functions:
Xss_clean () // xss filter
Sanitize_filename () // purify the file name
Do_hash () // md5 or sha encryption
Strip_image_tags () // remove unnecessary characters from the image tag
Encode_php_tags () // forcibly convert the PHP script tag to an object

 '[Removed]', 'document. write '=>' [removed] ','. parentNode '=>' [removed] ','. innerHTML '=>' [removed] ', 'window. location '=>' [removed] ','-moz-binding '=>' [removed] ','
 '=>' --> ',''=> '<![CDATA[','<comment>'=> '<comment>');//不允许出现的正则表达式数组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?");//构造函数public function __construct(){// CSRF保护是否开启if (config_item('csrf_protection') === TRUE){// CSRF配置foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key){if (FALSE !== ($val = config_item($key))){$this->{'_'.$key} = $val;}}// _csrf_cookie_name加上cookie前缀if (config_item('cookie_prefix')){$this->_csrf_cookie_name = config_item('cookie_prefix').$this->_csrf_cookie_name;}// 设置csrf的hash值$this->_csrf_set_hash();}log_message('debug', "Security Class Initialized");}// --------------------------------------------------------------------/** * Verify Cross Site Request Forgery Protection * * @returnobject */public function csrf_verify(){// 如果不是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?if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])){$this->csrf_show_error();}// token匹配吗if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name]){$this->csrf_show_error();}// We kill this since we're done and we don't want to// polute the _POST arrayunset($_POST[$this->_csrf_token_name]);// Nothing should last foreverunset($_COOKIE[$this->_csrf_cookie_name]);$this->_csrf_set_hash();$this->csrf_set_cookie();log_message('debug', 'CSRF token verified');return $this;}// --------------------------------------------------------------------/** * 设置csrf的cookie值 */public function csrf_set_cookie(){$expire = time() + $this->_csrf_expire;$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off')){return FALSE;}setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);log_message('debug', "CRSF cookie Set");return $this;}//csrf保存public function csrf_show_error(){show_error('The action you have requested is not allowed.');}//获取csrf的hash值public function get_csrf_hash(){return $this->_csrf_hash;}//获取csrf的token值public function get_csrf_token_name(){return $this->_csrf_token_name;}/** * XSS 过滤 */public function xss_clean($str, $is_image = FALSE){//是否是数组if (is_array($str)){while (list($key) = each($str)){$str[$key] = $this->xss_clean($str[$key]);}return $str;}//去掉可见字符串$str = remove_invisible_characters($str);// 验证实体url$str = $this->_validate_entities($str);/* * URL 解码 * * Just in case stuff like this is submitted: * * Google * * Note: Use rawurldecode() so it does not remove plus signs * */$str = rawurldecode($str);/* * Convert character entities to ASCII * * This permits our tests below to work reliably. * We only convert entities that are within tags since * these are the ones that will pose security problems. * */$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str);/* * Remove Invisible Characters Again! */$str = remove_invisible_characters($str);/* * Convert all tabs to spaces * * This prevents strings like this: javascript * NOTE: we deal with spaces between characters later. * NOTE: preg_replace was found to be amazingly slow here on * large blocks of data, so we use str_replace. */if (strpos($str, "\t") !== FALSE){$str = str_replace("\t", ' ', $str);}/* * Capture converted string for later comparison */$converted_string = $str;// Remove Strings that are never allowed$str = $this->_do_never_allowed($str);/* * Makes PHP tags safe * * Note: XML tags are inadvertently replaced too: * * <?xml * * But it doesn't seem to pose a problem. */if ($is_image === TRUE){// Images have a tendency to have the PHP short opening and// closing tags every so often so we skip those and only// do the long opening tags.$str = preg_replace('/<\?(php)/i', "<?\\1", $str);}else{$str = str_replace(array('<?', '?'.'>'),  array('<?', '?>'), $str);}/* * Compact any exploded words * * This corrects words like:  j a v a s c r i p t * These words are compacted back to their correct state. */$words = array('javascript', 'expression', 'vbscript', 'script', 'base64','applet', 'alert', 'document', 'write', 'cookie', 'window');foreach ($words as $word){$temp = '';for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++){$temp .= substr($word, $i, 1)."\s*";}// We only want to do this when it is followed by a non-word character// That way valid stuff like "dealer to" does not become "dealerto"$str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);}/* * Remove disallowed Javascript in links or img tags * We used to do some version comparisons and use of stripos for PHP5, * but it is dog slow compared to these simplified non-capturing * preg_match(), especially if the pattern exists in the string */do{$original = $str;if (preg_match("/]*?)(>|$)#si", array($this, '_js_link_removal'), $str);}if (preg_match("/]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);}if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str)){$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);}}while($original != $str);unset($original);// Remove evil attributes such as style, onclick and xmlns$str = $this->_remove_evil_attributes($str, $is_image);/* * Sanitize naughty HTML elements * * If a tag containing any of the words in the list * below is found, the tag gets converted to entities. * * So this: <blink> * Becomes: <blink> */$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);/* * Sanitize naughty scripting elements * * Similar to above, only instead of looking for * tags it looks for PHP and JavaScript commands * that are disallowed.  Rather than removing the * code, it simply converts the parenthesis to entities * rendering the code un-executable. * * For example:eval('some code') * Becomes:eval('some code') */$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str);// Final clean up// This adds a bit of extra precaution in case// something got through the above filters$str = $this->_do_never_allowed($str);/* * Images are Handled in a Special Way * - Essentially, we want to know that after all of the character * conversion is done whether any unwanted, likely XSS, code was found. * If not, we return TRUE, as the image is clean. * However, if the string post-conversion does not matched the * string post-removal of XSS, then it fails, as there was unwanted XSS * code found and removed/changed during processing. */if ($is_image === TRUE){return ($str == $converted_string) ? TRUE: FALSE;}log_message('debug', "XSS Filtering completed");return $str;}// --------------------------------------------------------------------//保护url的随机hash值public function xss_hash(){if ($this->_xss_hash == ''){mt_srand();$this->_xss_hash = md5(time() + mt_rand(0, 1999999999));}return $this->_xss_hash;}// --------------------------------------------------------------------/** * html实体转码 */public function entity_decode($str, $charset='UTF-8'){if (stristr($str, '&') === FALSE){return $str;}$str = html_entity_decode($str, ENT_COMPAT, $charset);$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);}// --------------------------------------------------------------------//过滤文件名,保证文件名安全public function sanitize_filename($str, $relative_path = FALSE){$bad = array("../","<!--","-->","<",">","'",'"','&','$','#','{','}','[',']','=',';','?',"%20","%22","%3c",// <"%253c",// <"%3e",// >"%0e",// >"%28",// ("%29",// )"%2528",// ("%26",// &"%24",// $"%3f",// ?"%3b",// ;"%3d"// =);if ( ! $relative_path){$bad[] = './';$bad[] = '/';}$str = remove_invisible_characters($str, FALSE);return stripslashes(str_replace($bad, '', $str));}//压缩单词如j a v a s c r i p t成javascriptprotected function _compact_exploded_words($matches){return preg_replace('/\s+/s', '', $matches[1]).$matches[2];}// --------------------------------------------------------------------/* * 去掉一些危害的html属性 */protected function _remove_evil_attributes($str, $is_image){// All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns$evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction');if ($is_image === TRUE){/* * Adobe Photoshop puts XML metadata into JFIF images,  * including namespacing, so we have to allow this for images. */unset($evil_attributes[array_search('xmlns', $evil_attributes)]);}do {$count = 0;$attribs = array();// find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER);foreach ($matches as $attr){$attribs[] = preg_quote($attr[0], '/');}// find occurrences of illegal attribute strings without quotespreg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);foreach ($matches as $attr){$attribs[] = preg_quote($attr[0], '/');}// replace illegal attribute strings that are inside an html tagif (count($attribs) > 0){$str = preg_replace('/(<?)(\/?[^><]+?)([^A-Za-z<>\-])(.*?)('.implode('|', $attribs).')(.*?)([\s><]?)([><]*)/i', '$1$2 $4$6$7$8', $str, -1, $count);}} while ($count);return $str;}// --------------------------------------------------------------------/** * 净化html,补齐未关闭的标签 */protected function _sanitize_naughty_html($matches){// encode opening brace$str = '<'.$matches[1].$matches[2].$matches[3];// encode captured opening or closing brace to prevent recursive vectors$str .= str_replace(array('>', '<'), array('>', '<'),$matches[4]);return $str;}// --------------------------------------------------------------------/** * 过滤超链接中js */protected function _js_link_removal($match){return str_replace($match[1],preg_replace('#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si','',$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))),$match[0]);}// --------------------------------------------------------------------/** * 过滤图片链接中的js */protected function _js_img_removal($match){return str_replace($match[1],preg_replace('#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si','',$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))),$match[0]);}// --------------------------------------------------------------------/** * 转换属性,将一些字符转换成实体 */protected function _convert_attribute($match){return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]);}// --------------------------------------------------------------------//过滤html标签属性protected function _filter_attributes($str){$out = '';if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches)){foreach ($matches[0] as $match){$out .= preg_replace("#/\*.*?\*/#s", '', $match);}}return $out;}// --------------------------------------------------------------------//html实体转码protected function _decode_entity($match){return $this->entity_decode($match[0], strtoupper(config_item('charset')));}// --------------------------------------------------------------------/** * 验证url实体 */protected function _validate_entities($str){/* * Protect GET variables in URLs */ // 901119URL5918AMP18930PROTECT8198$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);/* * Validate standard character entities * * Add a semicolon if missing.  We do this to enable * the conversion of entities to ASCII later. * */$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);/* * Validate UTF16 two byte encoding (x00) * * Just as above, adds a semicolon if missing. * */$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);/* * Un-Protect GET variables in URLs */$str = str_replace($this->xss_hash(), '&', $str);return $str;}// ----------------------------------------------------------------------//过滤不允许出现的字符串protected function _do_never_allowed($str){$str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);foreach ($this->_never_allowed_regex as $regex){$str = preg_replace('#'.$regex.'#is', '[removed]', $str);}return $str;}// --------------------------------------------------------------------//设置csrf的hash值protected function _csrf_set_hash(){if ($this->_csrf_hash == ''){// 如果_csrf_cookie_name存在,直接作为csrf hash值if (isset($_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];}                        //否则随机一个md5字符串return $this->_csrf_hash = md5(uniqid(rand(), TRUE));}return $this->_csrf_hash;}}</pre>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.