您的位置:首页 > 其它

XSS安全处理

2015-06-26 17:15 85 查看
Security.class.php文件

<?php
class Security {

public $filename_bad_chars =    array(
'../', '<!--', '-->', '<', '>',
"'", '"', '&', '$', '#',
'{', '}', '[', ']', '=',
';', '?', '%20', '%22',
'%3c',        // <
'%253c',    // <
'%3e',        // >
'%0e',        // >
'%28',        // (
'%29',        // )
'%2528',    // (
'%26',        // &
'%24',        // $
'%3f',        // ?
'%3b',        // ;
'%3d'        // =
);
protected $_xss_hash =    '';
protected $_never_allowed_str =    array(
'document.cookie'    => '[removed]',
'document.write'    => '[removed]',
'.parentNode'        => '[removed]',
'.innerHTML'        => '[removed]',
'-moz-binding'        => '[removed]',
'<!--'                => '<!--',
'-->'                => '-->',
'<![CDATA['            => '<![CDATA[',
'<comment>'            => '<comment>'
);
protected $_never_allowed_regex = array(
'javascript\s*:',
'(document|(document\.)?window)\.(location|on\w*)',
'expression\s*(\(|&\#40;)', // CSS and IE
'vbscript\s*:', // IE, surprise!
'Redirect\s+302',
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
);

public function gprc_xss(){
if($_POST)$_POST             = $this->xss_clean($_POST);
if($_GET)$_GET               = $this->xss_clean($_GET);
if($_COOKIE)$_COOKIE         = $this->xss_clean($_COOKIE);
if($_REQUEST)$_REQUEST       = $this->xss_clean($_REQUEST);
}

public function remove_invisible_characters($str, $url_encoded = TRUE){
$non_displayables = array();
if ($url_encoded)  {
$non_displayables[] = '/%0[0-8bcef]/';    // url encoded 00-08, 11, 12, 14, 15
$non_displayables[] = '/%1[0-9a-f]/';    // url encoded 16-31
}
$non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';    // 00-08, 11, 12, 14-31, 127
do {
$str = preg_replace($non_displayables, '', $str, -1, $count);
}
while ($count);
return $str;
}

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 = $this->_validate_entities($this->remove_invisible_characters($str));
$str = rawurldecode($str);
$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
$str = preg_replace_callback('/<\w+.*/si', array($this, '_decode_entity'), $str);
$str = $this->remove_invisible_characters($str);
$str = str_replace("\t", ' ', $str);
$converted_string = $str;
$str = $this->_do_never_allowed($str);
if ($is_image === TRUE){
$str = preg_replace('/<\?(php)/i', '<?\\1', $str);
}else    {
$str = str_replace(array('<?', '?'.'>'), array('<?', '?>'), $str);
}
$words = array(
'javascript', 'expression', 'vbscript', 'script', 'base64',
'applet', 'alert', 'document', 'write', 'cookie', 'window'
);
foreach ($words as $word){
$word = implode('\s*', str_split($word)).'\s*';
$str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
}
do{
$original = $str;
if (preg_match('/<a/i', $str))$str = preg_replace_callback('#<a\s+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
if (preg_match('/<img/i', $str))$str = preg_replace_callback('#<img\s+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
if (preg_match('/script|xss/i', $str))$str = preg_replace('#</*(?:script|xss).*?>#si', '[removed]', $str);
}
while ($original !== $str);
unset($original);
$str = $this->_remove_evil_attributes($str, $is_image);
$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);
$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',    '\\1\\2(\\3)',    $str);
$str = $this->_do_never_allowed($str);
if ($is_image === TRUE)return ($str === $converted_string);
return $str;
}

public function xss_hash(){
if ($this->_xss_hash === '')$this->_xss_hash = md5(uniqid(mt_rand()));
return $this->_xss_hash;
}

public function entity_decode($str, $charset = NULL){
if (strpos($str, '&') === FALSE)return $str;
if (empty($charset))$charset = 'utf-8';

do{
$matches = $matches1 = 0;
$str = preg_replace('~(�*[0-9a-f]{2,5});?~iS', '$1;', $str, -1, $matches);
$str = preg_replace('~(&#\d{2,4});?~S', '$1;', $str, -1, $matches1);
$str = html_entity_decode($str, ENT_COMPAT, $charset);
}
while ($matches OR $matches1);
return $str;
}

public function sanitize_filename($str, $relative_path = FALSE){
$bad = $this->filename_bad_chars;
if ( ! $relative_path){
$bad[] = './';
$bad[] = '/';
}
$str = $this->remove_invisible_characters($str, FALSE);
do{
$old = $str;
$str = str_replace($bad, '', $str);
}while ($old !== $str);
return stripslashes($str);
}

public function strip_image_tags($str){
return preg_replace(array('#<img[\s/]+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img[\s/]+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
}

protected function _compact_exploded_words($matches){
return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
}

protected function _remove_evil_attributes($str, $is_image){
$evil_attributes = array('style', 'xmlns', 'formaction');
if ($is_image === TRUE)unset($evil_attributes[array_search('xmlns', $evil_attributes)]);

do {
$count = 0;
$attribs = array();
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], '/');
}
preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
foreach ($matches as $attr){
$attribs[] = preg_quote($attr[0], '/');
}
if (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;
}

protected function _sanitize_naughty_html($matches)    {
return '<'.$matches[1].$matches[2].$matches[3].str_replace(array('>', '<'), array('>', '<'), $matches[4]);
}

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]);
}

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]);
}

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;
}

protected function _decode_entity($match){
return $this->entity_decode($match[0], strtoupper('utf-8'));
}

protected function _validate_entities($str){
$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash().'\\1=\\2', $str);
$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', '\\1;\\2', $str);
$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i', '\\1\\2;', $str);
return str_replace($this->xss_hash(), '&', $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;
}
/**
* @desc: 暂时不用
* */
public function gprc_sql(){
if(!get_magic_quotes_gpc()) {
if($_POST)    $_POST      =  $this->daddslashes($_POST);
if($_GET)     $_GET       =  $this->daddslashes($_GET);
if($_COOKIE)  $_COOKIE    =  $this->daddslashes($_COOKIE);
if($_REQUEST) $_REQUEST   =  $this->daddslashes($_REQUEST);
}
}

public function daddslashes($string){
if(!is_array($string)) return addslashes($string);
foreach($string as $key => $val) $string[$key] =  $this->daddslashes($val);
return $string;
}
}


调用方式:

$SEC = new Security();
$SEC->gprc_xss();
$SEC = NULL;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: