博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC 重写HttpMessageConverter进行Xss过滤
阅读量:7009 次
发布时间:2019-06-28

本文共 4950 字,大约阅读时间需要 16 分钟。

  hot3.png

在工作中,需要对xss攻击脚本过滤,在此记录下处理过程。

由于只需要对content-type=application/json;charset=UTF-8的json请求进行处理,所以需要重写MappingJacksonHttpMessageConverter部分方法。

注意:如果使用的是MappingJackson2HttpMessageConverter,需要重写MappingJackson2HttpMessageConverter部分方法  

  1. 定义接口MessageConverterHandler

    我们定义一个接口来定义我们需要实现的方法

public interface MessageConverterHandler
 { /**  * 用于在httpMessageConverter read(..)方法完成之后调用  * 

 * 1.可以对converter映射出的Object进行处理  * 

 */ public Object readAfter( T obj, K type );}

    2.自定义注解NeedXss

    该注解用于需要xss过滤的字段

@Target( ElementType.FIELD )@Retention( RetentionPolicy.RUNTIME )@Documentedpublic @interface NeedXss {}

    3.实现类XssMappingJacksonHttpMessageConverter,该类需要实现MessageConverterHandler,继承MappingJacksonHttpMessageConverter

    代码如下:

//默认会过滤所有请求路径,只会过滤String类型的字段,需要其他类型过滤的请自行完善public class XssMappingJacksonHttpMessageConverter extends MappingJacksonHttpMessageConverter implements		MessageConverterHandler
 { /**  * 不需要xss过滤的路径  */ protected static List
 urls; static { urls = new ArrayList
(); // for example urls.add("/xxx/xxxxx"); }                //重写该方法,我们只需要加上Object tempObj = this.process( obj, type, inputMessage );        //并返回tempObj,process方法里面我们过滤白名单和进行xss处理 @Override public Object read( Type type, Class
 contextClass, HttpInputMessage inputMessage ) throws IOException, HttpMessageNotReadableException { JavaType javaType = getJavaType( type, contextClass ); Object obj = readJavaType( javaType, inputMessage ); Object tempObj = this.process( obj, type, inputMessage ); return tempObj; } //这个就是父类的readJavaType方法,由于父类该方法是private的,所以我们copy一个用 private Object readJavaType( JavaType javaType, HttpInputMessage inputMessage ) { try { return super.getObjectMapper().readValue( inputMessage.getBody(), javaType ); } catch ( IOException ex ) { throw new HttpMessageNotReadableException( "Could not read JSON: " + ex.getMessage(), ex ); } }                 protected Object process( Object obj, Type type, HttpInputMessage inputMessage ) { if ( this.isNeedProcess( inputMessage ) ) { return this.readAfter( obj, type ); } else { return obj; } } //根据白名单,判断当前请求路径是否需要xss过滤 protected boolean isNeedProcess( HttpInputMessage inputMessage ) { String url = ""; try {         //经过debug发现inputMessage类型为ServletServerHttpRequest,所以进行下类型转换 ServletServerHttpRequest request = ( ServletServerHttpRequest ) inputMessage; url = request.getURI().getPath(); //根据白名单做下匹配,当然也可以实现正则什么的,代码就不贴了 } catch ( Exception e ) { logger.error( "BACK_ERROR," + this.getClass().getCanonicalName() + ",XSS处理-url处理失败,url=" + url + ",ERROR=", e ); return true; } return true; } //最重要的一步,进行xss过滤 @Override public Object readAfter( Object obj, Type type ) { try {         //type实际上就是我们需要convert的model,我们通过反射来完成根据NeedXss注解对String         //的字段进行xss过滤 Class clazz = Class.forName( JSON.toJSONString( type ).replace( "\"", "" ) ); if ( clazz == null ) { return obj; } Field[] fields = clazz.getDeclaredFields(); if ( fields != null && fields.length > 0 ) { // string类型字段名称列表 List
 strList = new ArrayList
( fields.length ); // 1. 将需要xss处理的string类型的字段放入strlist for ( int i = 0; i < fields.length; i++ ) {         // 1.1该属性是否有NeedXss.class注解 NeedXss needXss = fields[ i ].getAnnotation( NeedXss.class ); // 1.2如果该没有NeedXss.class注解,则不处理该属性 if ( needXss == null || !( needXss instanceof NeedXss ) ) { continue; } String mod = Modifier.toString( fields[ i ].getModifiers() ); if ( mod.indexOf( "static" ) != -1 ) continue; // 得到属性的类名 String className = fields[ i ].getType().getSimpleName(); // 得到属性字段名 if ( className.equalsIgnoreCase( "String" ) ) { strList.add( fields[ i ].getName() ); } } // 2.将strlist中的字段进行xss处理 if ( strList.size() > 0 ) { Object temp = JSON.toJavaObject( ( JSON ) JSON.toJSON( obj ), clazz ); for ( int i = 0; i < strList.size(); i++ ) { Method set = clazz.getMethod( "set" + strList.get( i ).substring( 0, 1 ).toUpperCase() + strList.get( i ).substring( 1 ), String.class ); Method get = clazz.getMethod( "get" + strList.get( i ).substring( 0, 1 ).toUpperCase() + strList.get( i ).substring( 1 ) ); Object tempObj = get.invoke( temp ); if ( tempObj == null ) { break; } String content = tempObj.toString(); set.invoke( temp, StringUtils.cleanXss( content ) ); } return temp; } } } catch ( Exception e ) { logger.error( "BACK_ERROR," + this.getClass().getCanonicalName() + ",XSS处理失败,obj=" + JSON.toJSONString( obj ) + ",javaType=" + JSON.toJSONString( type ) + ",ERROR=", e ); return obj; } return obj; }}

    4.配置使用自定义的XssMappingJacksonHttpMessageConverter

    在SpringMVC的配置文件里面加上下面的配置

    

   最后,不出意外应该就是可以啦

转载于:https://my.oschina.net/jayhu/blog/653725

你可能感兴趣的文章
LeetCode-Best Time to Buy and Sell Stock I&&II
查看>>
Java compiler level does not match解决方法(转)
查看>>
ROS初级教程 cmake cmakelist.txt 的编写教程
查看>>
Comparing Inline and Multi-Statement Table valued UDFs
查看>>
python 机器学习
查看>>
php如何控制客户端生成缓存
查看>>
不错的在线印章生成器网站
查看>>
Arduino控制LCD显示helloworld
查看>>
线程、任务和同步学习笔记(一)
查看>>
JavaScript this
查看>>
OpenJudge/Poj 1163 The Triangle
查看>>
POJ 3130 半平面交+模版改进
查看>>
Python基础二
查看>>
AndroidStudio -- AndroidStuido中找不到cache.properties文件
查看>>
nginx 无法访问root权限的文件内容
查看>>
进程和线程有什么区别?
查看>>
关于text-align无法居中的问题
查看>>
Here We Go(relians) Again
查看>>
Signal函数
查看>>
[Errno 14] PYCURL ERROR 7 - "couldn't connect to host"
查看>>