PHP防止XSS跨站指令碼攻擊的方法:是針對非法的HTML程式碼包括單雙引號等,使用htmlspecialchars()函式 。
在使用htmlspecialchars()函式的時候注意第二個引數, 直接用htmlspecialchars($string) 的話,第二個引數預設是ENT_COMPAT,函式預設只是轉化雙引號(“), 不對單引號(‘)做轉義.
所以,htmlspecialchars函式更多的時候要加上第二個引數, 應該這樣用: htmlspecialchars($string,ENT_QUOTES).當然,如果需要不轉化如何的引號,用htmlspecialchars($string,ENT_NOQUOTES).
另外, 儘量少用htmlentities, 在全部英文的時候htmlentities和htmlspecialchars沒有區別,都可以達到目的.但是,中文情況下, htmlentities卻會轉化所有的html程式碼,連同裡面的它無法識別的中文字元也給轉化了。
htmlentities和htmlspecialchars這兩個函式對 '之類的字串支援不好,都不能轉化, 所以用htmlentities和htmlspecialchars轉化的字串只能防止XSS攻擊,不能防止SQL隱碼攻擊.
所有有列印的語句如echo,print等 在列印前都要使用htmlentities() 進行過濾,這樣可以防止Xss,注意中文要寫出htmlentities($name,ENT_NOQUOTES,GB2312) 。
(1).網頁不停地重新整理 '<meta http-equiv="refresh" content="0;">'
(2).嵌入其它網站的連結 <iframe src=http://xxxx width=250 height=250></iframe> 除了通過正常途徑輸入XSS攻擊字元外,還可以繞過JavaScript校驗,通過修改請求達到XSS攻擊的目的.
<?php //php防注入和XSS攻擊通用過濾 $_GET && SafeFilter($_GET); $_POST && SafeFilter($_POST); $_COOKIE && SafeFilter($_COOKIE); function SafeFilter (&$arr) { $ra=Array('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/','/script/','/javascript/','/vbscript/','/expression/','/applet/' ,'/meta/','/xml/','/blink/','/link/','/style/','/embed/','/object/','/frame/','/layer/','/title/','/bgsound/' ,'/base/','/onload/','/onunload/','/onchange/','/onsubmit/','/onreset/','/onselect/','/onblur/','/onfocus/', '/onabort/','/onkeydown/','/onkeypress/','/onkeyup/','/onclick/','/ondblclick/','/onmousedown/','/onmousemove/' ,'/onmouseout/','/onmouseover/','/onmouseup/','/onunload/'); if (is_array($arr)) { foreach ($arr as $key => $value) { if (!is_array($value)) { if (!get_magic_quotes_gpc()) //不對magic_quotes_gpc轉義過的字元使用addslashes(),避免雙重轉義。 { $value = addslashes($value); //給單引號(')、雙引號(")、反斜線(\)與 NUL(NULL 字元) 加上反斜線轉義 } $value = preg_replace($ra,'',$value); //刪除非列印字元,粗暴式過濾xss可疑字串 $arr[$key] = htmlentities(strip_tags($value)); //去除 HTML 和 PHP 標記並轉換為 HTML 實體 } else { SafeFilter($arr[$key]); } } } } ?> $str = 'www.90boke.com<meta http-equiv="refresh" content="0;">'; SafeFilter ($str); //如果你把這個註釋掉,提交之後就會無休止重新整理 echo $str;
//------------------------------php防注入和XSS攻擊通用過濾-----Start--------------------------------------------// function string_remove_xss($html) { preg_match_all("/\<([^\<]+)\>/is", $html, $ms); $searchs[] = '<'; $replaces[] = '<'; $searchs[] = '>'; $replaces[] = '>'; if ($ms[1]) { $allowtags = 'img|a|font|div|table|tbody|caption|tr|td|th|br|p|b|strong|i|u|em|span|ol|ul|li|blockquote'; $ms[1] = array_unique($ms[1]); foreach ($ms[1] as $value) { $searchs[] = "<".$value.">"; $value = str_replace('&', '_uch_tmp_str_', $value); $value = string_htmlspecialchars($value); $value = str_replace('_uch_tmp_str_', '&', $value); $value = str_replace(array('\\', '/*'), array('.', '/.'), $value); $skipkeys = array('onabort','onactivate','onafterprint','onafterupdate','onbeforeactivate','onbeforecopy','onbeforecut','onbeforedeactivate', 'onbeforeeditfocus','onbeforepaste','onbeforeprint','onbeforeunload','onbeforeupdate','onblur','onbounce','oncellchange','onchange', 'onclick','oncontextmenu','oncontrolselect','oncopy','oncut','ondataavailable','ondatasetchanged','ondatasetcomplete','ondblclick', 'ondeactivate','ondrag','ondragend','ondragenter','ondragleave','ondragover','ondragstart','ondrop','onerror','onerrorupdate', 'onfilterchange','onfinish','onfocus','onfocusin','onfocusout','onhelp','onkeydown','onkeypress','onkeyup','onlayoutcomplete', 'onload','onlosecapture','onmousedown','onmouseenter','onmouseleave','onmousemove','onmouseout','onmouseover','onmouseup','onmousewheel', 'onmove','onmoveend','onmovestart','onpaste','onpropertychange','onreadystatechange','onreset','onresize','onresizeend','onresizestart', 'onrowenter','onrowexit','onrowsdelete','onrowsinserted','onscroll','onselect','onselectionchange','onselectstart','onstart','onstop', 'onsubmit','onunload','javascript','script','eval','behaviour','expression','style','class'); $skipstr = implode('|', $skipkeys); $value = preg_replace(array("/($skipstr)/i"), '.', $value); if (!preg_match("/^[\/|\s]?($allowtags)(\s+|$)/is", $value)) { $value = ''; } $replaces[] = empty($value) ? '' : "<" . str_replace('"', '"', $value) . ">"; } } $html = str_replace($searchs, $replaces, $html); return $html; } //php防注入和XSS攻擊通用過濾 function string_htmlspecialchars($string, $flags = null) { if (is_array($string)) { foreach ($string as $key => $val) { $string[$key] = string_htmlspecialchars($val, $flags); } } else { if ($flags === null) { $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string); if (strpos($string, '&#') !== false) { $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string); } } else { if (PHP_VERSION < '5.4.0') { $string = htmlspecialchars($string, $flags); } else { if (!defined('CHARSET') || (strtolower(CHARSET) == 'utf-8')) { $charset = 'UTF-8'; } else { $charset = 'ISO-8859-1'; } $string = htmlspecialchars($string, $flags, $charset); } } } return $string; } //------------------php防注入和XSS攻擊通用過濾-----End--------------------------------------------//
PHP中的設定
PHP5.2以上版本已支援HttpOnly引數的設定,同樣也支援全域性的HttpOnly的設定,在php.ini中
-----------------------------------------------------
session.cookie_httponly =
-----------------------------------------------------
設定其值為1或者TRUE,來開啟全域性的Cookie的HttpOnly屬性,當然也支援在程式碼中來開啟:
<?php ini_set("session.cookie_httponly", 1); // or session_set_cookie_params(0, NULL, NULL, NULL, TRUE); ?>
Cookie操作函式setcookie函式和setrawcookie函式也專門新增了第7個引數來做為HttpOnly的選項,開啟方法為:
<?php setcookie("abc", "test", NULL, NULL, NULL, NULL, TRUE); setrawcookie("abc", "test", NULL, NULL, NULL, NULL, TRUE); ?>
老版本的PHP就不說了。沒企業用了吧。