好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用springMVC通过Filter实现防止xss注入

springMVC Filter防止xss注入

跨站脚本工具(cross 斯特scripting),为不和层叠样式表(cascading style sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。

恶意攻击者往web页面里插入恶意scriptScript代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

防止XSS攻击简单的预防就是对Request请求中的一些参数去掉一些比较敏感的脚本命令。

原本是打算通过springMVC的HandlerInterceptor机制来实现的,通过获取request然后对request中的参数进行修改,结果虽然值修改了,但在Controller中获取的数值还是没有修改的。没办法就是要Filter来完成。

简单来说就是创建一个新的httpRequest类XsslHttpServletRequestWrapper,然后重写一些get方法(获取参数时对参数进行XSS判断预防)。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

@WebFilter (filterName= "xssMyfilter" ,urlPatterns= "/*" )

public class MyXssFilter implements Filter{

     @Override

     public void init(FilterConfig filterConfig) throws ServletException {      

     }

 

     @Override

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

             throws IOException, ServletException {

         XsslHttpServletRequestWrapper xssRequest = new XsslHttpServletRequestWrapper((HttpServletRequest)request);

         chain.doFilter(xssRequest , response);

     }

    

     @Override

     public void destroy() {    

     }  

}

XSS代码的过滤是在XsslHttpServletRequestWrapper中实现的,主要是覆盖实现了getParameter,getParameterValues,getHeader这几个方法,然后对获取的value值进行XSS处理。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

public class XsslHttpServletRequestWrapper extends HttpServletRequestWrapper {

   HttpServletRequest xssRequest = null ; 

  public XsslHttpServletRequestWrapper(HttpServletRequest request) {

   super (request);

   xssRequest = request;

  }

 

   @Override

   public String getParameter(String name) { 

        String value = super .getParameter(replaceXSS(name)); 

          if (value != null ) { 

              value = replaceXSS(value); 

          } 

          return value; 

   } 

  

   @Override

  public String[] getParameterValues(String name) {

    String[] values = super .getParameterValues(replaceXSS(name));

    if (values != null && values.length > 0 ){

     for ( int i = 0 ; i< values.length ;i++){

      values[i] = replaceXSS(values[i]);

     }

    }

   return values;

   }

  

   @Override

   public String getHeader(String name) { 

   

          String value = super .getHeader(replaceXSS(name)); 

          if (value != null ) { 

              value = replaceXSS(value); 

          } 

          return value; 

      }

   /**

    * 去除待带script、src的语句,转义替换后的value值

    */

  public static String replaceXSS(String value) {

      if (value != null ) {

          try {

           value = value.replace( "+" , "%2B" );   //'+' replace to '%2B'

           value = URLDecoder.decode(value, "utf-8" );

          } catch (UnsupportedEncodingException e){

          } catch (IllegalArgumentException e){

      }

         

    // Avoid null characters

    value = value.replaceAll( "\0" , "" );

 

    // Avoid anything between script tags

    Pattern scriptPattern = Pattern测试数据pile( "<script>(.*?)</script>" , Pattern.CASE_INSENSITIVE);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    // Avoid anything in a src='...' type of e­xpression

    scriptPattern = Pattern测试数据pile( "src[\r\n]*=[\r\n]*\\\'(.*?)\\\'" , Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    scriptPattern = Pattern测试数据pile( "src[\r\n]*=[\r\n]*\\\"(.*?)\\\"" , Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    // Remove any lonesome </script> tag

    scriptPattern = Pattern测试数据pile( "</script>" , Pattern.CASE_INSENSITIVE);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    // Remove any lonesome <script ...> tag

    scriptPattern = Pattern测试数据pile( "<script(.*?)>" , Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    // Avoid eval(...) e­xpressions

    scriptPattern = Pattern测试数据pile( "eval\\((.*?)\\)" , Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    // Avoid e­xpression(...) e­xpressions

    scriptPattern = Pattern测试数据pile( "e­xpression\\((.*?)\\)" , Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    value = scriptPattern.matcher(value).replaceAll( "" );

 

    // Avoid javascript:... e­xpressions

    scriptPattern = Pattern测试数据pile( "javascript:" , Pattern.CASE_INSENSITIVE);

    value = scriptPattern.matcher(value).replaceAll( "" );

    // Avoid alert:... e­xpressions

    scriptPattern = Pattern测试数据pile( "alert" , Pattern.CASE_INSENSITIVE);

    value = scriptPattern.matcher(value).replaceAll( "" );

    // Avoid οnlοad= e­xpressions

    scriptPattern = Pattern测试数据pile( "onload(.*?)=" , Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    value = scriptPattern.matcher(value).replaceAll( "" );

    scriptPattern = Pattern测试数据pile( "vbscript[\r\n| | ]*:[\r\n| | ]*" , Pattern.CASE_INSENSITIVE); 

    value = scriptPattern.matcher(value).replaceAll( "" );

   }        

      return filter(value);

  } 

   /**

    * 过滤特殊字符

    */

   public static String filter(String value) {

          if (value == null ) {

              return null ;

          }       

          StringBuffer result = new StringBuffer(value.length());

          for ( int i= 0 ; i<value.length(); ++i) {

              switch (value.charAt(i)) {

               case '<' :

                   result.append( "<" );

                   break ;

               case '>' :

                   result.append( ">" );

                   break ;

               case '"' :

                   result.append( "" ");

                   break ;

               case '\'' :

                   result.append( "'" );

                   break ;

               case '%' :

                   result.append( "%" );

                   break ;

               case ';' :

                   result.append( ";" );

                   break ;

            case '(' :

                   result.append( "(" );

                   break ;

               case ')' :

                   result.append( ")" );

                   break ;

               case '&' :

                   result.append( "&" );

                   break ;

               case '+' :

                   result.append( "+" );

                   break ;

               default :

                   result.append(value.charAt(i));

                   break ;

           } 

          }

          return result.toString();

      }

}

SpringMVC 防止XSS 工具(常规方式)

要求:

xss过滤请求的参数:Content-Type为 json(application/json)

SpringMVC 对于application/json 转换处理说明:

spring mvc默认使用MappingJackson2HttpMessageConverter转换器,

而它是使用jackson来序列化对象的,如果我们能 将jackson的序列化和反序列化过程修改,加入过滤xss代码,并将其注册到MappingJackson2HttpMessageConverter中

具体实现功能代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

import java.io.IOException;

import org.apache测试数据mons.text.StringEscapeUtils;

import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.DeserializationContext;

import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

 

/**

  * 反序列化

  *

  */

public class XssDefaultJsonDeserializer extends StdDeserializer<String> {

  public XssDefaultJsonDeserializer(){

   this ( null );

  }

 

  public XssDefaultJsonDeserializer(Class<String> vc) {

   super (vc);

  }

 

  @Override

  public String deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {

   // TODO Auto-generated method stub

   //return StringEscapeUtils.escapeEcmaScript(jsonParser.getText());

   return StringEscapeUtils.unescapeHtml4(jsonParser.getText());

  }

}

SpringMVC 配置对象:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@Configuration

@EnableWebMvc

public class SpingMVCConfig extends WebMvcConfigurerAdapter {

  @Override

  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

   super .configureMessageConverters(converters);

   // TODO Auto-generated method stub

   SimpleModule module = new SimpleModule();

   // 反序列化

   module.addDeserializer(String. class , new XssDefaultJsonDeserializer());

   // 序列化

   module.addSerializer(String. class , new XssDefaultJsonSerializer());

   ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build();

   // 注册自定义的序列化和反序列化器

   mapper.registerModule(module);

   MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);

   converters.add(converter);

           }

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://tianjunwei.blog.csdn.net/article/details/62053577

查看更多关于使用springMVC通过Filter实现防止xss注入的详细内容...

  阅读:36次