web系统对安全漏洞的部分控制
在spring,springmvc构建的web系统中,普遍存在部分xss的安全漏洞,一般分为以下几种情况,下面针对每一种情况来做一下xss的过滤。
技术的背景:spring5,springmvc,tomcat用war包部署
url的xss过滤
在springmvc中,过滤url的xss,可以通过定制自己的UrlPathHelper来做处理。首先在springmvc.xml中加入自定义的UrlPathHelper:
<bean id="xssPathHelper" class="你的包.XssUrlPathHelper"></bean>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<ref bean="stringHttpMessageConverter"/>
<ref bean="jsonHttpMessageConverter"/>
</mvc:message-converters>
<mvc:path-matching path-helper="xssPathHelper"/>
</mvc:annotation-driven>
自定义的XssUrlPathHelper:
public class XssUrlPathHelper extends UrlPathHelper{
@Override
public Map<String, String> decodePathVariables(HttpServletRequest request, Map<String, String> vars) {
Map<String, String> result = super.decodePathVariables(request, vars);
if(!ContainerUtil.isEmpty(result)){
for(String key : result.keySet()){
result.put(key, cleanXSS(result.get(key)));
}
}
return result;
}
private String cleanXSS(String value){
return HtmlUtils.htmlEscape(value);
}
}
请求params的xss过滤
请求参数的过滤可以使用过滤器XssFilter进行过滤,web.xml中配置过滤器。
<filter>
<filter-name>XssFilter</filter-name>
<filter-class>com.elementspeed.common.filter.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
XssFilter类:
public class XssFilter implements Filter {
FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new XssHttpServletRequestWrapper(
(HttpServletRequest) request), response);
}
}
对应的XssHttpServletRequestWrapper:
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values==null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = XssUtil.cleanXSS(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return XssUtil.cleanXSS(value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return XssUtil.cleanXSS(value);
}
}
formdata的xss过滤
如果使用formdata提交,则参数方式无法过滤,需要使用@InitBinder
@InitBinder
public void initBinder(WebDataBinder binder) {
//去掉参数的前后空格
binder.registerCustomEditor(String.class, new XssStringEditor(true));
}
对应的XssStringEditor:
public class XssStringEditor extends StringTrimmerEditor{
public XssStringEditor(boolean emptyAsNull) {
super(emptyAsNull);
}
@Override
public void setAsText(@Nullable String text) {
if(!StringUtils.isEmpty(text)) {
text = XssUtil.cleanXSS(text);
}
super.setAsText(text);
}
}
ajax的xss过滤
ajax的提交数据在body里面,上面的都拦截不到,需要自定义json的转换器,springmvc.xml中配置:
<bean id="jsonHttpMessageConverter" class="你的包.XSSMappingJackson2HttpMessageConverter">
<property name="prettyPrint" value="true" />
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
对应的转换器类:XSSMappingJackson2HttpMessageConverter
public class XSSMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter{
@Override
public Object read(Type type, Class<?> contextClass,
HttpInputMessage inputMessage) throws IOException,
HttpMessageNotReadableException {
Object obj = super.read(type,contextClass, inputMessage);
Object resultObj = null;
try {
String json = super.getObjectMapper().writeValueAsString(obj);
String result = cleanXSS(json.toString());
JavaType javaType = getJavaType(type, contextClass);
resultObj = super.getObjectMapper().readValue(result, javaType);
}catch (Exception e) {
return obj;
}
return resultObj;
}
private String cleanXSS(String value) {
return XssUtil.cleanXSS(value);
}
}
通用工具类,因为多个地方都使用,所以用一个工具类统一处理:
public class XssUtil {
public static String cleanXSS(String value) {
value = value.replaceAll("<", "<").replaceAll(">", ">");
/*value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
value = value.replaceAll("'", "& #39;"); */
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("[s|S][c|C][r|R][i|C][p|P][t|T]", "");
//value = value.replaceAll("src[\\r\\n]*=[\\r\\n]*\\\\\\'(.*?)\\\\\\'", "");
//value = value.replaceAll("src[\\r\\n]*=[\\r\\n]*\\\\\\\"(.*?)\\\\\\\"", "");
value = value.replaceAll("script", "");
return value;
}
}