跨站脚本(Cross site script,简称xss)是一种“HTML注入”,由于攻击的脚本多数时候是跨域的,所以称之为“跨域脚本”。
我们常常听到“注入”(Injection),如SQL注入,那么到底“注入”是什么?注入本质上就是把输入的数据变成可执行的程序语句。SQL注入是如此,XSS也如此,只不过XSS一般注入的是恶意的脚本代码,这些脚本代码可以用来获取合法用户的数据,如Cookie信息。
或者当访问者浏览网页时恶意代码会被执行或者通过给管理员发信息的方式诱使管理员浏览,从而获得管理员权限,控制整个网站
攻击者利用跨站请求伪造能够轻松地强迫用户的浏览器发出非故意的HTTP请求,如诈骗性的电汇请求、修改口令和下载非法的内容等请求。
风险等级:高危
该漏洞可能被攻击者利用窃取或操纵客户会话和Cookie,它们可能用于模仿合法用户,从而使黑客能够以合法用户身份登录系统进行渗透。可执行攻击者恶意脚本。
在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。
在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
在标签的 href、src 等属性中,包含
javascript:
等可执行代码。在 onload、onerror、onclick 等事件中,注入不受控制代码。
在 style 属性和标签中,包含类似
background-image:url("javascript:…");
的代码(新版本浏览器已经可以防范)。在 style 属性和标签中,包含类似
expression(…)
的 CSS 表达式代码(新版本浏览器已经可以防范)。
本文基于JavaWeb后端考虑,前端可参考: 前端安全系列:如何防止XSS攻击?:
javax.servlet
servlet-api
3.0-alpha-1
provided
xssFilter
com.newcapec.cloudpay.filter.XssFilter
xssFilter
*
自定义过滤器Filter拦截请求,并对请求参数进行xss过滤处理
package com.newcapec.cloudpay.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Title: XSS过滤器
* @ClassName: com.newcapec.cloudpay.filter.XssFilter.java
* @Description:
*
* @Copyright 2016-2018 Powered By 研发中心
* @author: 王延飞
* @date: 2019-01-24 16:22
* @version V1.0
*/
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//使用包装器
XSSRequestWrapper XSSRequestWrapper=new XSSRequestWrapper((HttpServletRequest) servletRequest);
filterChain.doFilter(XSSRequestWrapper,servletResponse);
}
@Override
public void destroy() {
}
}
package com.newcapec.cloudpay.filter;
import org.apache.commons.lang.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* @version V1.0
* @Title: Request的包装类
* @ClassName: com.newcapec.cloudpay.filter.XSSRequestWrapper.java
* @Description: XSSRequestWrapper是Request的包装类, 用于修改Request请求,这是拦截器Interceptor所不能做到的
* @Copyright 2016-2018 Powered By 研发中心
* @author: 王延飞
* @date: 2019-01-25 9:15
*/
public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* @param name
* @return java.lang.String[]
* @Title: 对数组参数进行特殊字符过滤
* @methodName: getParameterValues
* @Description:
* @author: 王延飞
* @date: 2019-01-25 10:23
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = clearXss(values[i]);
}
return encodedValues;
}
/**
* @param name
* @return java.lang.String
* @Title: 对参数中特殊字符进行过滤
* @methodName: getParameter
* @Description:
* @author: 王延飞
* @date: 2019-01-25 10:23
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
return clearXss(value);
}
/**
* @Title: 覆盖getParameterMap方法,将参数名和参数值都做xss & sql过滤
* @methodName: getParameterMap
* @param
* @return java.util.Map
* @Description: 覆盖getParameterMap方法,将参数名和参数值都做xss & sql过滤
* 【一般post表单请求,或者前台接收为实体需要这样处理】
*
* @author: 王延飞
* @date: 2019-02-20 11:12
*/
@Override
public Map getParameterMap() {
Map paramMap = new HashMap();
Map requestMap = super.getParameterMap();
Iterator> it = requestMap.entrySet().iterator();
while (it.hasNext()) {
Entry entry = it.next();
if(entry.getValue().length==1){
paramMap.put(xssEncode(entry.getKey()), xssEncode(entry.getValue()[0]));
} else {
String[] values = entry.getValue();
String value = "";
for(int i=0; i",">");
value = value.replaceAll("'","'");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("(?i).*?", "");
value = value.replaceAll("(?i).*? ", "");
value = value.replaceAll("(?i)<.*?javascript:.*?>.*?", "");
value = value.replaceAll("(?i)<.*?\\s+on.*?>.*?", "");
// value = value.replaceAll("[<>{}\\[\\];\\&]","");
return value;
}
}
package com.newcapec.cloudpay.filter;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @version V1.0
* @Title:
* @ClassName: com.newcapec.cloudpay.filter.XssFilterUtil.java
* @Description:
* @Copyright 2016-2018 Powered By 研发中心
* @author: 王延飞
* @date: 2019-01-25 9:11
*/
public class XssFilterUtil {
private static final Logger log = LoggerFactory.getLogger(XssFilterUtil.class);
private static List patterns = null;
/**
* @param
* @return java.util.List
* @Title: XSS常见攻击
* @methodName: getXssPatternList
* @Description: Pattern.MULTILINE(? m):在这种模式下,'^'和'$'分别匹配一行的开始和结束。此外,'^'仍然匹配字符串的开始,'$'也匹配字符串的结束。
* 默认情况下,这两个表达式仅仅匹配字符串的开始和结束。
*
* Pattern.DOTALL(?s) :在这种模式下,表达式'.'可以匹配任意字符,包括表示一行的结束符。
* 默认情况下,表达式'.'不匹配行的结束符。
* @author: 王延飞
* @date: 2019-01-25 9:11
*/
private static List
- 控制台输出信息:
2019-01-25 11:50:37:512 com.newcapec.cloudpay.filter.XssFilterUtil.stripXss(XssFilterUtil.java:104) 【XSS攻击防御】,接收字符是:
2019-01-25 11:50:37:513 com.newcapec.cloudpay.filter.XssFilterUtil.stripXss(XssFilterUtil.java:118) 【XSS攻击防御】,匹配正则是:java.util.regex.Matcher[pattern=<+\s*\w*\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|οnerrοr=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\s*=+ region=0,0 lastmatch=],处理后是:
2019-01-25 11:50:37:513 com.newcapec.cloudpay.controller.test.RsaControllerTest.testXSS(RsaControllerTest.java:64) 【防御XSS】,客户端端name是: