スプリングmvcでxss攻撃を防ぐ

5762 ワード

インターネットでいくつかの方法を調べました。
1.フィルターを書き、HttpServletRequest Wrapperと彼のget Paraameter Valuesと get Parameeter方法は、この方法が可能ですが、@Requset Bodyパラメータに対しては無効です。
Spring MVCの@Request Paramで取得したパラメータに対して、get Parameter Values()の方法を実行します。 
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class XssFilter implements Filter {

    public void init(FilterConfig config) throws ServletException {}

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest)request);
        chain.doFilter(xssRequest, response);
    }

    public void destroy() {}
}
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    HttpServletRequest orgRequest = null;

    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        orgRequest = request;
    }
    /**
     *   getParameter  ,          xss  。
* , super.getParameterValues(name)
* getParameterNames,getParameterValues getParameterMap */ @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] = xssEncode(values[i]); } return encodedValues; } @Override public String getParameter(String name) { String value = super.getParameter(xssEncode(name)); System.out.println("before name:"+name +" value:"+value); if (value != null) { value = xssEncode(value); } System.out.println("after name:"+name +" value:"+value); return value; } /** * getHeader , xss 。
* , super.getHeaders(name)
* getHeaderNames */ @Override public String getHeader(String name) { String value = super.getHeader(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * xss * * @param s * @return */ private static String xssEncode(String s) { if (s == null || s.isEmpty()) { return s; } StringBuilder sb = new StringBuilder(s.length() + 16); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); switch (c) { case '>': sb.append('>');// break; case '= index + 2){ if(s.charAt(index+1) == '3' && (s.charAt(index+2) == 'c' || s.charAt(index+2) == 'C')){ // %3c, %3C sb.append('<'); return; } if(s.charAt(index+1) == '6' && s.charAt(index+2) == '0'){ // %3c (0x3c=60) sb.append('<'); return; } if(s.charAt(index+1) == '3' && (s.charAt(index+2) == 'e' || s.charAt(index+2) == 'E')){ // %3e, %3E sb.append('>'); return; } if(s.charAt(index+1) == '6' && s.charAt(index+2) == '2'){ // %3e (0x3e=62) sb.append('>'); return; } } sb.append(s.charAt(index)); } /** * request * * @return */ public HttpServletRequest getOrgRequest() { return orgRequest; } /** * request * * @return */ public static HttpServletRequest getOrgRequest(HttpServletRequest req) { if (req instanceof XssHttpServletRequestWrapper) { return ((XssHttpServletRequestWrapper) req).getOrgRequest(); } return req; } }

    XssFilter
    com.glodio.filter.XssFilter
    
   
  
  
    XssFilter
    /*
  
これは特殊文字列を全部変えます。
2 springバンドのSteringEscape Utilsを使用して特殊フィールドを変換します。
  System.out.println(StringEscapeUtils.escapeHtml(「dd」);  System.out.printel(StringEscapeUtils.escapeHtml);
//出力結果
<a>ddddalert('111')
フィールドを直接に変換します。
@InitBinder
protected void initBinder(WebDataBinder binder) {
	// String    ,        String  HTML  ,  XSS  
	binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
		@Override
		public void setAsText(String text) {
			setValue(text == null ? null : StringEscapeUtils.escapeHtml(text.trim()));
		}
		@Override
		public String getAsText() {
			Object value = getValue();
			return value != null ? value.toString() : "";
		}
	});
}

必要に応じて一つを選ぶことができます。