防止XSS攻击(sql注入)

web.xml配置:

<filter>
	<filter-name>xssFilter</filter-name>
	<filter-class>com.inspur.tax.sst.util.filter.XSSFilter</filter-class>
</filter>

<!-- 解决xss漏洞 -->
<filter-mapping>
	<filter-name>xssFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

java代码:

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.util.StringUtils;

/** 
* @author 
* @version 创建时间:2017年3月17日 下午5:04:40 
* Xss过滤器
*/
public class XSSFilter implements Filter {

	private static Logger log = LoggerFactory.getLogger(XSSFilter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String requestURI = request.getRequestURI();
    	response.setHeader("Content-Security-Policy","default-src 'self'");//这个响应头主要是用来定义页面可以加载哪些资源,减少XSS的发生
    	response.setHeader("X-Content-Type-Options","nosniff");//互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。通过这个响应头可以禁用浏览器的类型猜测行为
    	response.setHeader("X-XSS-Protection","1; mode=block");//1; mode=block:启用XSS保护,并在检查到XSS攻击时,停止渲染页面

		//为服务器配置允许的http请求
		String method=((HttpServletRequest)request).getMethod();
		if(!"GET".equals(method)&&!"POST".equals(method)&&!"HEAD".equals(method))
		{
			log.error("The request with-Method【"+method+"】was forbidden-by-server!");
			response.setContentType("text/html;charset=GBK");
			response.setCharacterEncoding("GBK");
			((HttpServletResponse)response).setStatus(403);
			response.getWriter().print("<font size=6 color=red>对不想,生的请求非念。莱统推她响应!</font>");
			return;
		} 		
		if("/service/wszcx/list".equals(requestURI)||"/service/sst/authorize".equals(requestURI))
		{
			chain.doFilter(req, res);
		}
		else
		{
			String strBackUrl = "http://" + request.getServerName() // 服务器地址
					+ ":" + request.getServerPort() // 端口号
					+ request.getContextPath() // 项目名称
					+ request.getServletPath() // 请求页面或其他地址
					+ "?"; // 参数  + (request.getQueryString())
			// get
			String cs = request.getQueryString();
			// post
			Map arrMap = request.getParameterMap();
			for(Iterator iter=arrMap.entrySet().iterator();iter.hasNext();){  
		        Map.Entry element=(Map.Entry)iter.next();  
		        //key值  
		        Object strKey = element.getKey(); 
		        cs += "&" + strKey + "=";
		        //value,数组形式  
		        String[] value=(String[])element.getValue();  
		  
	        StringBuffer buf = new StringBuffer();
	        for(int i=0;i<value.length;i++){  
	        	buf.append(value[i] + ",");
	        } 
	        cs += buf.toString(); 
			}
			//strBackUrl += cs;
			String strBackUrl_=strBackUrl + cs;
			// 过滤
			log.info("当前请求地址为:"+ strBackUrl);
			//添加防止sql注入校验checkSQLInject
			if (isXSS(strBackUrl_)||checkSQLInject(cs,strBackUrl)) {
				if (log.isInfoEnabled()) {
					log.info("XSSrequest=========" + strBackUrl_);
					log.info("可能为XSS攻击");
				}
				response.sendRedirect("/jsp/public/500.jsp");
				return;
			} else {
				chain.doFilter(req, res);
				return;
			}
		}
	}

	@Override
	public void destroy() {
	}

	private boolean isXSS(String s) {
		if (s == null || s.isEmpty()) {
			return false;
		}
		if (s.indexOf("<") != -1 || s.indexOf("%3C") != -1 || s.indexOf("%3c") != -1) {
			return true;
		}
		if (s.indexOf(">") != -1 || s.indexOf("%3E") != -1 || s.indexOf("%3e") != -1) {
			return true;
		}
//		if (s.indexOf("'") != -1 || s.indexOf("%27") != -1) {
//			return true;
//		}
		if (s.indexOf("(") != -1 || s.indexOf("%28") != -1) {
			return true;
		}
		if (s.indexOf(")") != -1 || s.indexOf("%29") != -1) {
			return true;
		}
		if (s.indexOf("(") != -1 || s.indexOf("%EF%BC%88") != -1) {
			return true;
		}
		if (s.indexOf(")") != -1 || s.indexOf("%EF%BC%89") != -1) {
			return true;
		}
		//20190117   liushudong 
		String reg = "(?:’)|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"+"(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|union|drop|execute)\\b)";
		Pattern sqlPt = Pattern.compile(reg,Pattern.CASE_INSENSITIVE);
		if(sqlPt.matcher(s).find()){
			return true;
		}

		//		if (s.indexOf("{") != -1) {
//			return true;
//		}
//		if (s.indexOf("}") != -1) {
//			return true;
//		}
//		if (s.indexOf("\"") != -1) {
//			return true;
//		}
		
		if (s.indexOf("%0a") != -1) {
			return true;
		}
		if (s.indexOf("%0d") != -1) {
			return true;
		}
		if (s.indexOf("javascript") != -1) {
			return true;
		}
		if (s.indexOf("script") != -1) {
			return true;
		}
		return false;
	}
	/**
	 * 
	 * 检查是否存在非法字符,防止SQL注入  20190926  lfp
	 * 
	 * @param str
	 *            被检查的字符串
	 * @return ture-字符串中存在非法字符,false-不存在非法字符
	 */
	public static boolean checkSQLInject(String str, String url) {
		if (StringUtils.isEmpty(str)) {
			return false;// 如果传入空串则认为不存在非法字符
		}
 
		// 判断黑名单
		String[] inj_stra = { "script ", "mid ", "master ", "truncate ", "insert ", "select ", "delete ", "update ", "declare ",
				"iframe ","onreadystatechange ", "alert", "atestu ", "exec ", "master ",  "svg ", "confirm ", "prompt ", "onload ",
				"onmouseover", "onfocus","#", "onerror", "net user" , "asc\\(","drop table","count\\(","mid\\(", "char\\(", "or ", "and "};


		str = str.toLowerCase(); // sql不区分大小写

 
		for (int i = 0; i < inj_stra.length; i++) {
			if (str.indexOf(inj_stra[i]) >= 0) {
				log.info("xss防攻击拦截url:" + url + ",原因:特殊字符,传入str=" + str + ",包含特殊字符:" + inj_stra[i]);
				return true;
			}
		}
		return false;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值