PHP针对Xss跨域攻击以及sql注入等危险字符串过滤安全模块

由于该模块在项目中的要求是 不能提示任何信息,也不作断点操作,只作记录并且过滤危险参数。

主要功能:拦截攻击者注入恶意代码,可以防御诸如跨站脚本攻击(XSS)、SQL注入攻击等恶意攻击行为。

<?php
/**
 * 安全模块
 * Email:zhangyuan@tieyou.com
 * 主要针对xss跨站攻击、sql注入等敏感字符串进行过滤
 * @author hkshadow
 */
class safeMode{
	
	/**
	 * 执行过滤
	 * @param 1 linux/2 http/3 Db/ $group
	 * @param 保存路径以及文件名/文件名/null $projectName
	 */
	public function xss($group = 1,$projectName = NULL){
		//正则条件
		$referer = empty ( $_SERVER ['HTTP_REFERER'] ) ? array () : array ($_SERVER ['HTTP_REFERER'] );
		$getfilter = "'|<[^>]*?>|^\\+\/v(8|9)|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
		$postfilter = "^\\+\/v(8|9)|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*img\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
		$cookiefilter = "\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";

		// $ArrPGC=array_merge($_GET,$_POST,$_COOKIE);

		//遍历过滤
		foreach ( $_GET as $key => $value ) {
			$this->stopAttack ( $key, $value, $getfilter ,$group , $projectName);
		}
		//遍历过滤
		foreach ( $_POST as $key => $value ) {
			$this->stopAttack ( $key, $value, $postfilter ,$group , $projectName);
		}
		//遍历过滤
		foreach ( $_COOKIE as $key => $value ) {
			$this->stopAttack ( $key, $value, $cookiefilter ,$group , $projectName);
		}
		//遍历过滤
		foreach ( $referer as $key => $value ) {
			$this->stopAttack ( $key, $value, $getfilter ,$group , $projectName);
		}
	}
	
	/**
	 * 匹配敏感字符串,并处理
	 * @param 参数key $strFiltKey
	 * @param 参数value $strFiltValue
	 * @param 正则条件 $arrFiltReq
	 * @param 项目名 $joinName
	 * @param 1 linux/2 http/3 Db/ $group
	 * @param 项目名/文件名/null $projectName
	 */
	public function stopAttack($strFiltKey, $strFiltValue, $arrFiltReq,$group = 1,$projectName = NULL) {
		
			$strFiltValue = $this->arr_foreach ( $strFiltValue );
			//匹配参数值是否合法
			if (preg_match ( "/" . $arrFiltReq . "/is", $strFiltValue ) == 1) {
				//记录ip
				$ip = "操作IP: ".$_SERVER["REMOTE_ADDR"];
				//记录操作时间
				$time = " 操作时间: ".strftime("%Y-%m-%d %H:%M:%S");
				//记录详细页面带参数
				$thePage = " 操作页面: ".$this->request_uri();
				//记录提交方式
				$type = " 提交方式: ".$_SERVER["REQUEST_METHOD"];
				//记录提交参数
				$key = " 提交参数: ".$strFiltKey;
				//记录参数
				$value = " 提交数据: ".htmlspecialchars($strFiltValue);
				//写入日志
				$strWord = $ip.$time.$thePage.$type.$key.$value;
				//保存为linux类型
				if($group == 1){
					$this->log_result_common($strWord,$projectName);
				}
				//保存为可web浏览
				if($group == 2){
					$strWord .= "<br>";
					$this->slog($strWord,$projectName);
				}
				//保存至数据库
				if($group == 3){
					$this->sDb($strWord);	
				}
				//过滤参数
				$_REQUEST[$strFiltKey] = '';
				//这里不作退出处理
				//exit;
			}
			
			//匹配参数是否合法
			if (preg_match ( "/" . $arrFiltReq . "/is", $strFiltKey ) == 1) {
				//记录ip
				$ip = "操作IP: ".$_SERVER["REMOTE_ADDR"];
				//记录操作时间
				$time = " 操作时间: ".strftime("%Y-%m-%d %H:%M:%S");
				//记录详细页面带参数
				$thePage = " 操作页面: ".$this->request_uri();
				//记录提交方式
				$type = " 提交方式: ".$_SERVER["REQUEST_METHOD"];
				//记录提交参数
				$key = " 提交参数: ".$strFiltKey;
				//记录参数
				$value = " 提交数据: ".htmlspecialchars($strFiltValue);
				//写入日志
				$strWord = $ip.$time.$thePage.$type.$key.$value;
				//保存为linux类型
				if($group == 1){
					$this->log_result_common($strWord,$projectName);
				}
				//保存为可web浏览
				if($group == 2){
					$strWord .= "<br>";
					$this->slog($strWord,$projectName);
				}
				//保存至数据库
				if($group == 3){
					$this->sDb($strWord);	
				}
				//过滤参数
				$_REQUEST[$strFiltKey] = '';
				//这里不作退出处理
				//exit;
			}
		}
	
	/**
	 * 获取当前url带具体参数
	 * @return string
	 */
	public function request_uri() {
		if (isset ( $_SERVER ['REQUEST_URI'] )) {
			$uri = $_SERVER ['REQUEST_URI'];
		} else {
			if (isset ( $_SERVER ['argv'] )) {
				$uri = $_SERVER ['PHP_SELF'] . '?' . $_SERVER ['argv'] [0];
			} else {
				$uri = $_SERVER ['PHP_SELF'] . '?' . $_SERVER ['QUERY_STRING'];
			}
		}
		return $uri;
	}
	

	/**
	 * 日志记录(linux模式)
	 * @param 保存内容 $strWord
	 * @param 保存文件名$strPathName
	 */
	public function log_result_common($strWord, $strPathName = NULL) {
		if($strPathName == NULL){
			$strPath = "/var/tmp/";
			$strDay = date('Y-m-d');
			$strPathName = $strPath."common_log_".$strDay.'.log';
		}
	
		$fp = fopen($strPathName,"a");
		flock($fp, LOCK_EX) ;
		fwrite($fp,$strWord." date ".date('Y-m-d H:i:s',time())."\t\n");
		flock($fp, LOCK_UN);
		fclose($fp);
	}	
	
	/**
	 * 写入日志(支持http查看)
	 * @param 日志内容 $strWord
	 * @param web页面文件名 $fileName
	 */
	public function slog($strWord,$fileName = NULL) {
		if($fileName == NULL){
			$toppath = $_SERVER ["DOCUMENT_ROOT"] . "/log.htm";
		}else{
			$toppath = $_SERVER ["DOCUMENT_ROOT"] .'/'. $fileName;
		}
		$Ts = fopen ( $toppath, "a+" );
		fputs ( $Ts, $strWord . "\r\n" );
		fclose ( $Ts );
	}
	
	/**
	 * 写入日志(数据库)
	 * @param 日志内容 $strWord
	 */
	public function sDb($strWord){
		//....
	}
	
	/**
	 * 递归数组
	 * @param array $arr
	 * @return unknown|string
	 */
	public function arr_foreach($arr) {
		static $str = '';
		if (! is_array ( $arr )) {
			return $arr;
		}
		foreach ( $arr as $key => $val ) {
			if (is_array ( $val )) {
				$this->arr_foreach ( $val );
			} else {
				$str [] = $val;
			}
		}
		return implode ( $str );
	}
}
?>

使用:

<?php
//实例类库
$safeMode = new safeMode();
//这里的参数指的的时 类型,保存的文件名,具体请看类注视。
$safeMode->xss(2,'test.html');
?>

至此基本上,参数带有危险的字符串的时候,将其过滤,并且保存日志到网站根目录的test.html内,可在浏览器预览查看。

《PHP针对Xss跨域攻击以及sql注入等危险字符串过滤安全模块》有3条评论

评论已关闭。