作者:只属于天天的牛牛 | 来源:互联网 | 2023-05-25 13:14
1.脚本注入攻击
例如:
更多请参考:
XSS脚本注入 - 美女爱找茬 - 博客园 (cnblogs.com)
那么怎么来预防这类攻击?
我们可以添加参数过滤,例如:
增加对get请求,form表单,json数据的过滤
将这五个文件导入项目即可
a.新建get请求和表单过滤的转义类
文件中是针对参数值含有"<" ">"进行转义,如果有特殊要求,可以自己写正则或其它
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;/**** XXS转义*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String getParameter(String name) {String value = super.getParameter(name);if (!StringUtils.isEmpty(value)) {//如果请求参数的值含有"<",">" 则转义if (value.contains("<") || value.contains(">")) {value = HtmlUtils.htmlEscape(value);}}return value;}@Overridepublic String[] getParameterValues(String name) {String[] parameterValues = super.getParameterValues(name);if (parameterValues == null) {return null;}for (int i = 0; i " 则转义if (value.contains("<") || value.contains(">")) {parameterValues[i] = HtmlUtils.htmlEscape(value);}}}return parameterValues;}
}
注:JS和JQuery都提供转义的函数,在此不介绍了。
后端,Spring也提供了转义的方法:
/** HTML转义 **/
String s = HtmlUtils.htmlEscape("hello world
");
System.out.println(s);
String s2 = HtmlUtils.htmlUnescape(s);
System.out.println(s2); 结果:
hello world
hello world
为什么要转义? 转义的目的是防止前端传送的参数,影响后端的响应,带出一些关键的信息。例如:COOKIEs等等。
如果我们不想转义,可以直接进行删除或替换。
如果有特殊的要求,可以继承HttpServletRequestWrapper.java 然后根据自己的要求来重新相关的方法。
b.json
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import java.io.IOException;
import java.lang.reflect.Type;
/**
*json*/public class XSSMappingJackson2HttpMessageConverter extendsMappingJackson2HttpMessageConverter {private ObjectMapper mapper = new ObjectMapper();public XSSMappingJackson2HttpMessageConverter() {super();mapper.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());}@Overridepublic Object read(Type type, Class> contextClass,HttpInputMessage inputMessage) throws IOException,HttpMessageNotReadableException {JavaType javaType = getJavaType(type, contextClass);// 下面的对@RequestBody的信息做XSS过滤try {// json字串转实体Object object = mapper.readValue(inputMessage.getBody(), javaType);// 实体转字串String jsOnString= mapper.writeValueAsString(object);// json字串转实体object = mapper.readValue(jsonString, javaType);return object;} catch (IOException ex) {throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);}}
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.web.util.HtmlUtils;
import java.io.IOException;
/***/
public class XssStringJsonSerializer extends JsonSerializer {@Overridepublic Class handledType() {return String.class;}@Overridepublic void serialize(String value, JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException {if (value != null) {String encodedValue = HtmlUtils.htmlEscape(value);jsonGenerator.writeString(encodedValue);}}
}
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;public class XssFilter implements Filter {FilterConfig filterCOnfig= null;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {this.filterCOnfig= filterConfig;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;XssHttpServletRequestWrapper xssRequestWrapper = new XssHttpServletRequestWrapper(req);chain.doFilter(xssRequestWrapper, response);}@Overridepublic void destroy() {this.filterCOnfig= null;}@Beanpublic MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {return new XSSMappingJackson2HttpMessageConverter();}@Beanpublic XssStringJsonSerializer xssStringJsonSerializer(){return new XssStringJsonSerializer();}
}
web.xml 新增配置:
xssFilterdemo.XssFilterxssFilter/*
关于重定向攻击:
我们使用过滤器来处理:
a.新建过滤器
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/***/
public class XssRedirectFilter implements Filter {public final static String REDIRECT_URL = "redirectUrl";//一但发现攻击,跳转到我们指定的网址(根据实际修改)public final static String DEFAULT_URL = "http://www.lili.study.com";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse resp = (HttpServletResponse)response;String uri = req.getRequestURI();String redirectUrl = req.getParameter(REDIRECT_URL);if (redirectUrl != null) {String xssPath = PropertiesUtil.getXssPath();String[] xssPaths = xssPath.split(",");List list = Arrays.asList(xssPaths);if(list.contains(uri)){String[] paths = redirectUrl.split(REDIRECT_URL);//如果有两个及两个以上重定向url,则默认重定向到DEFAULT_URLif (paths.length >= 3) {resp.sendRedirect(DEFAULT_URL);return;}//重定向为一个,判断重定向的路径中,是否包含guanyi或edgjString path = paths[0];if(path.contains("?")){path = path.substring(0,path.indexOf("?"));}//如果跳转的路径,不包含我们的字段,则跳转if(!path.contains("lili") && !path.contains("ll")){resp.sendRedirect(DEFAULT_URL);return;}}}filterChain.doFilter(request,response);}@Overridepublic void destroy() {}
}
2.获取属性的工具类(默认需要拦截的是登录接口)
package gy.erp.util;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;/***/
@Component
public class PropertiesUtil {private static String xssPath;//需要拦截的接口,指定拦截@Value("${xss.path.filter:/login}")public void setXssPath(String xssPath) {PropertiesUtil.xssPath=xssPath;}public static String getXssPath() {return xssPath;}
}
如果想拦截所有,则不需要该类,并且去除XssRedirectFilter.java相关的代码即可。
3.配置web.xml
xssPathFilterdemo.XssRedirectFilterxssPathFilter/*
可以根据实际情况做相应的调整修改。