`

xssFilter

 
阅读更多
xss过滤器


import XSSRexConstants;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* a fine-grained xss filter based on blacklist
*
*/
// @WebFilter("/xssFilter")
public class XSSCheckFilter implements Filter {

/**
* 处理multipart请求
*/
private CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();

// 黑名单,要求全部小写
// 可疑关键字、函数、标签、事件,函数加左括号,标签加左尖括号,事件加等号。
private static final String blackList[] = new String[] {
// 可疑关键字
"`",
"javascript",
"@import",
"x:script",
"window.location",
"jscript",
"vbscript",
"http-equiv",
"![cdata[",
"with(document)",
// 可疑标签
"<iframe",
"<frameset",
"<marquee",
"<form",
"<object",
"<applet",
"<embed",
"<meta",
"<value",
"<comment>",
"<!doctype",
"<script",
// 可疑函数
"$.get(",
"$.getscript(",
"alert(",
"unescape(",
"execscript(",
"eval(",
"prompt(",
"msgbox(",
"fromcharcode(",
"encodeuri(",
"encodeuricomponent(",
"confirm(",
// 可疑事件
"autofocus=", "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=",
"window.location", "<![CDATA[<svg]]>", "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=", "onhaschange=", "onmessage=",
"onoffline=", "ononline=", "onpagehide=", "onpageshow=",
"onpopstate=", "onredo=", "onstorage=", "onundo=", "onformchange=",
"onforminput=", "oninput=", "oninvalid=", "oncanplay=",
"oncanplaythrough=", "ondurationchange=", "onemptied=", "onended=",
"onloadeddata=", "onloadedmetadata=", "onloadstart=", "onpause=",
"onplay=", "onplaying=", "onprogress=", "onratechange=",
"onreadystatechange=", "onseeked=", "onseeking=", "onstalled=",
"onsuspend=", "ontimeupdate=", "onvolumechange=", "onwaiting=",
"ontoggle=", "onshow=", "onwheel=", "onsearch=", ".replace(",
".concat(", "join(", "&amp;tab;" };

/**
* Default constructor.
*/
public XSSCheckFilter() {

}

/**
* @see Filter#destroy()
*/
public void destroy() {

}

/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
request.setCharacterEncoding("UTF-8");

if (ServletFileUpload.isMultipartContent((HttpServletRequest) request)) {
DefaultMultipartHttpServletRequest multiReq = (DefaultMultipartHttpServletRequest) multipartResolver
.resolveMultipart((HttpServletRequest) request);

Enumeration<?> enu = multiReq.getParameterNames();
// 遍历参数
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
String[] values = multiReq.getParameterValues(name);
if (values != null) {
for (String value : values) {
if (!isXssSafe(value)) {

System.out.println(name);
httpResponse
.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
}

}
}

chain.doFilter(multiReq, response);
return;
} else {
Enumeration<?> enu = request.getParameterNames();
// 遍历参数
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
String[] values = request.getParameterValues(name);
if (values != null) {
for (String value : values) {
if (!isXssSafe(value)) {
httpResponse
.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
}

}
}
chain.doFilter(request, response);
}
}

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {

}

/**
* 根据输入key和value判断value是否为xss payload
* 目前的实现没有用到key值,若需要根据key来特殊化规则,可以传入key值并在filter方法中添加个性化实现 isXssSafe(String
* key, String value)
*
* @param key
*            http请求参数中的key
* @param value
*            http请求参数中的value
* @return 若判断value为xss payload,则返回false,否则返回true
*
*/
/**
* @param value
* @param value
* @return
*/
public static boolean isXssSafe(String value) {
if (StringUtils.isEmpty(value)) {
return true;
}
/**** 长度限制 ****/
// 若可能,请根据key来限制value的输入长度
/**** 格式校验 ****/
// 若可能,请根据key对value做格式校验

/**** 规范化 ****/
/**
* 全角转半角
*
*/
value = Normalizer.normalize(value, Form.NFC);
// html entity解码
// 包含实体名称解码、实体编号解码(实体编号后面不带;则不会解码)
value = StringEscapeUtils.unescapeHtml4(value);
// 多行转为单行
value = toSingleLine(value);
// 转换为小写
value = value.toLowerCase();

/**** Payload特征,假设正常报文不会出现 ****/
// 注释
if (value.matches(XSSRexConstants.REX_COMMENT)) {
return false;
}

// /正则/.source
if (value.matches(XSSRexConstants.REX_REX_SOURCE)) {
return false;
}

// &{()}
if (value.matches(".*&\\{.*\\}.*")) {
return false;
}

/**** 编码特征,假设正常报文不会出现 ****/
// 十进制编码
if (getCountByRex(value, "&?#\\d{1,7};?", true) > 0) {
return false;
}

// 十六进制编码
if (getCountByRex(value, "&#[x|X][0-9a-f]{1,};?", true) > 0) {
return false;
}
if (getCountByRex(value, "\\\\[x|X][0-9a-fA-F]{1,}", true) > 0) {
return false;
}

// unicode编码
if (getCountByRex(value, "\\\\u?[0-9a-fA-F]{1,}", true) > 0) {
return false;
}
if (getCountByRex(value, "%u[0-9a-fA-F]{4}", true) > 0) {
return false;
}
if (getCountByRex(value, "\\\\u\\{.*\\}", true) > 0) {
return false;
}

// url编码
if (getCountByRex(value, "%[0-9a-fA-F]{2}", true) > 0) {
return false;
}

// ascii转换
if (getCountByRex(value, "chr\\(\\d+\\)", true) > 0) {
return false;
}

// jjencode
if (getCountByRex(value, "\\[.*?\\]", false) > 5/* magic number */) {// 使用非贪心的正则匹配[]、
			return false;
		}

		/**** 净化 ****/
		// 移除特殊字符
		value = value.replaceAll("/", ""); // 移除'/'
		value = value.replaceAll("\\\\", ""); // 移除'\'
		value = value.replaceAll("\\+", ""); // 移除'+'
		value = value.replaceAll("\'", ""); // 移除'''
		value = value.replaceAll("\"", ""); // 移除'"'

		/**** 关键字过滤 ****/
		// 黑名单过滤
		for (String keyword : blackList) {
			if (value.contains(keyword)) {
				return false;
			}
		}

		// 特定场景过滤
		// data+base64
		if (value.matches(XSSRexConstants.REX_DATA_BASE64)) {
			return false;
		}
		// src
		if (value.matches(XSSRexConstants.REX_SRC)) {
			return false;
		}
		// href
		if (value.matches(XSSRexConstants.REX_HREF)) {
			return false;
		}
		// style
		if (value.matches(XSSRexConstants.REX_STYLE)) {
			return false;
		}
		// document.cookie with(document)cookie document.location
		if (value.matches(XSSRexConstants.REX_DOCUMENT)) {
			return false;
		}
		// location.hash
		if (value.matches(XSSRexConstants.REX_LOCATION_HASH)) {
			return false;
		}
		// js expression
		if (value.matches(XSSRexConstants.REX_JS_EXPRESSION)) {
			return false;
		}

		// 数组的join方法
		if (value.matches(XSSRexConstants.REX_JOIN)) {
			return false;
		}

		return true;
	}

	/**
	 * 根据正则在字符串中查找,返回正则匹配到的次数
	 *
	 * @param str
	 * @param pattern
	 * @param stopFast
	 *            若为true,则匹配到1次就返回,此时@return返回1
	 * @return
	 */
	private static int getCountByRex(String str, String pattern,
			boolean stopFast) {
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(str);
		int count = 0;
		while (m.find()) {
			count++;
			if (stopFast) {
				break;
			}
		}
		return count;
	}

	private static String toSingleLine(String value) {
		Pattern pattern = Pattern.compile("\\s"); // 匹配任何空白字符,包括空格、制表符、换页符等。与 [
		// \f\n\r\t\v] 等效。
		Matcher matcher = pattern.matcher(value);
		value = matcher.replaceAll("");
		return value;
	}

}


public class XSSRexConstants {

    public static final String REX_COMMENT = "(.*<!--.*-->.*)|(.*/\\*.*\\*/.*)";
    public static final String REX_DATA_BASE64 = ".*data.*;base64.*";
    public static final String REX_REX_SOURCE = ".*\\/.*\\/\\.source.*";
    public static final String REX_JS_EXPRESSION = ".*expression.*\\(.*\\).*";
    public static final String REX_JOIN = ".*join.*\\(.*\\).*";
    public static final String REX_HREF = ".*<.*href.*=.*>.*";
    public static final String REX_LOCATION_HASH = ".*location.*hash.*";
    public static final String REX_DOCUMENT = ".*document.*(cookie|location).*";
    public static final String REX_SRC = ".*<.*src.*";
    public static final String REX_STYLE = ".*<.*style.*";
    public static final String REX_JJ = ".*\\[.*?\\].*";
}

调用:
XSSCheckFilter.isXssSafe(servletRequest.getRequestURI())
					&& XSSCheckFilter
							.isXssSafe(servletRequest.getQueryString())
分享到:
评论

相关推荐

    预防XSS攻击和SQL注入XssFilter

    &lt;filter-name&gt;XssFilter&lt;/filter-name&gt; &lt;filter-class&gt;com.xxx.Filter.XssFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;XssFilter&lt;/filter-name&gt; &lt;url-pattern&gt;/* &lt;/filter-mapping&gt;

    XSSFilter源码

    ### XSSFilter源码详解 #### 一、XSSFilter概览 XSSFilter是一种用于防止跨站脚本攻击(Cross-Site Scripting,简称XSS)的安全组件。它通过过滤HTTP请求中的潜在恶意数据来阻止XSS攻击的发生。在本文档中,我们将...

    Springboot配置XSS过滤器XssFilter.zip

    直接可以运行,包含测试类,对HTML和SQL进行过滤,方便扩展。并且可以配置不拦截的路径,包含注释,方便学习。 博客地址:https://blog.csdn.net/u011974797/article/details/121792680

    关于pdf文件xss攻击问题,配置xssFilter方法

    3. 自定义XSSFilter:如果需要更细粒度的控制,可以创建自定义的XSSFilter类,重写`doFilter`方法,进行特定的XSS清理逻辑。这通常包括对请求参数、响应内容的清洗,去除或转义可能引发XSS的特殊字符。 4. 配置过滤...

    SpringBoot整合XssFilter,Jsoup等实现请求参数的过滤,处理Xss攻击及sql注入.zip

    原理过程 Springboot中会使用FilterRegistrationBean来注册Filter,Filter是Servlet规范里面的,属于容器范围,Springboot中没有web.xml,那Springboot中,不用管Filter是如何交给Ser...SpringBoot整合XssFilter,...

    第十节 xss filter过滤器-01

    XSS_Filter_过滤器详解 在Web应用程序中,XSS(Cross-Site Scripting)是一种常见的安全漏洞。攻击者可以通过在Web应用程序中 inject 恶意脚本,从而获取用户的敏感信息或控制用户的行为。为了防止这种攻击,开发者...

    白盒审计下XSS Filter绕过技巧详解及解决方案

    内容概要:本文深入探讨了白盒审计中的XSS Filter绕过技巧,主要包括浏览器容错特性、属性内容编码、伪协议利用、数据URI协议等具体案例。同时提出了多种有效的富文本XSS防护方案,如使用HTML Purifier、UBB代码和...

    防止SQL注入和XSS攻击Filter

    public class XssFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { ...

    xssfilter:适用于Symphony CMS中事件的XSS筛选器

    另外,可以通过Extension_XSSFilter::detectXSS($string)直接在您的扩展中使用XSS过滤器,该扩展Extension_XSSFilter::detectXSS($string)接受一个字符串,如果检测到XSS,则返回布尔值。 前端实用程序 从XSS Filter...

    Bypassing Internet Explorer's XSS Filter

    ### 绕过Internet Explorer 9 的 XSS 过滤器:深度解析 在黑帽大会(Black Hat Conference)上,一篇名为《绕过Internet Explorer 9 的 XSS 过滤器》的论文引起了广泛关注。作者迈克尔·布鲁克斯(Michael Brooks)...

    前端开源库-xss-filters

    在前端开发中,XSS(Cross-site scripting)攻击是一种常见的安全威胁,它允许攻击者通过注入恶意脚本到网页上,从而控制用户浏览器的行为。"前端开源库-xss-filters"是一个专门针对这种情况设计的开源库,其目标是...

    XSS-Filter-Evasion-Cheat-Sheet

    XSS Filter Evasion Cheat Sheet 是一个专门针对如何检测和规避XSS过滤器的实用指南。下面将详细探讨XSS攻击的基本原理、类型以及如何利用XSS Filter Evasion技巧进行防御。** ### XSS攻击的基本概念 1. **反射型...

    SpringBoot整合XSS.zip

    本文将深入探讨如何使用SpringBoot整合XssFilter和Jsoup来防范这些攻击。 **一、XSS攻击与防御** 1. **XSS攻击简介**:XSS(Cross Site Scripting)是一种常见的网络攻击方式,攻击者通过在网页上注入恶意脚本,...

    xss过滤.zip

    在提供的"XssHttpServletRequestWrapper.java"和"XSSFilter.java"这两个文件中,我们可以看到开发者如何实现这个过程。 `XssHttpServletRequestWrapper.java`文件是自定义的一个HTTP请求包装器,它的目的是在请求被...

    javaweb配置xssproject,完美解决安全检测报XSS漏洞

    2. **初始化XSSFilter**:在Web应用的初始化阶段,创建XSSFilter实例并设置相应的过滤策略。这可能需要调用XSSFilter类的静态方法,或者通过Web容器的filter配置实现。 3. **配置过滤链**:根据项目需求,定义哪些...

    AntiSamy Xss跨站脚本攻击WebService War包下载

    webapps\XssFilter3\WEB-INF\conf\antisamy-config.xml 保存后,重启Tomcat即可生效。 默认WebService地址是 http://[youserver]:[yourport]/XssFilter3/services/AntiSamyFilter .net环境下得到wsdl的地址是 ...

    xss_javaxss_XSS_

    4. 自定义过滤器:在给定的文件名“XssFilter.java”中,很可能定义了一个自定义的Servlet Filter,用于拦截和处理请求。这种过滤器可以在HTTP请求到达实际处理代码之前,对请求参数进行清洗或编码,防止XSS攻击。...

    java过滤器,防止XSS、SQL

    java过滤器,XSS : 跨站脚本攻击(Cross Site Scripting),SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令

    防止XSS攻击解决办法

    &lt;filter-name&gt;XSSFilter&lt;/filter-name&gt; &lt;filter-class&gt;com.example.XSSFilterClass&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;XSSFilter&lt;/filter-name&gt; &lt;url-pattern&gt;/* &lt;/filter-mapping&gt; ``` ...

Global site tag (gtag.js) - Google Analytics