公司的安全部门检测出来,我们的页面有xss漏洞,链接后带上alert,页面会弹出alert
https://www.**.html?starType=%22/%3E%3Csvg/οnlοad=alert(1022)%3E
安全部门推荐过滤特殊字符来解决,我们此处通过encoderequest参数来解决
为了避免不同方法都要去html转码, 我们新建一个拦截器来处理。
一、新建interceptor
package com.*
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.HtmlUtils;
public class XssInterceptor extends HandlerInterceptorAdapter {
// private final static Log log = LogFactory.getLog(XssInterceptor.class);
private boolean enabled = true; // 默认为启用
private final static String DEFAULT_JSONP_CALLBACK_NAME = "callback"; // jsonp默认回调函数名
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws IOException, MalformedURLException {
if (!enabled) { // 禁用后直接返回
return true;
}
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 获取页面提交到action前参数
Map map = request.getParameterMap();
// jsonp回调函数名是否已处理
boolean isJsonpCallbackHandled = false;
if (method.isAnnotationPresent(ResponseBody.class)) {
isJsonpCallbackHandled = true;
String[] args = (String[]) map.get(DEFAULT_JSONP_CALLBACK_NAME);
if(null != args){
for (int i = 0; i < args.length; i++) {
args[i] = HtmlUtils.htmlEscape(args[i]);
}
request.setAttribute(DEFAULT_JSONP_CALLBACK_NAME, args);
}
}
if (!method.isAnnotationPresent(XssCheck.class)) {
return true;
}
if (map != null && !map.isEmpty()) {
Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
// 该参数已经处理
if (isJsonpCallbackHandled && DEFAULT_JSONP_CALLBACK_NAME.equals(key)) {
continue;
}
Object t = map.get(key);
if (t instanceof String) {// 给String转码
if (t != null) {
t = HtmlUtils.htmlEscape((String)t);
}
}
if (t instanceof String[]) {// 给String数组转码
if (t != null) {
String[] args = (String[]) t;
String[] tmp = (String[]) t;
for (int i = 0; i < args.length; i++) {
args[i] = HtmlUtils.htmlEscape(tmp[i]);// 转码类
}
t = args;
}
}
request.setAttribute(key, t);
}
}
return true;
}
}
二、为了防止有的方法不需要做xss漏洞处理,我们新加一个注解,添加了此注解的方法才走此拦截器逻辑
package com.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface XssCheck {
boolean value() default true;
}
三、controller方法里添加注解
@RequestMapping(value = "/test/{id}.html")
@JProfiler(jKey = UmpConstant.WARE_SKU_CONTROLLER, jAppName = UmpConstant.APP_NAME, mState = { JProEnum.TP, JProEnum.FunctionError })
public @XssCheck ModelAndView test( HttpServletResponse response, HttpServletRequest request) {
........
}
四、xml配置
<mvc:interceptors>
<bean class="com.*.XssInterceptor"/>
</mvc:interceptors>
是