(공통처리)웹취약성 크로스사이트 스크립트(XSS) 처리하기2_filter chain :: 개발/일상_Mr.lee

(공통처리)웹취약성 크로스사이트 스크립트(XSS) 처리하기2_filter chain

Posted by Mr.mandu.
2019. 3. 14. 14:43 개발/java,spring

안녕하세요.

앞서 크로스사이트 스크립트(XSS)를 처리하기 위하여 포스팅한적이 있습니다.

이는 간단한 경우에 임시로 처리하기 위함이었습니다.


[개발/web, html5,jsp] - 웹취약성 크로스사이트 스크립트(XSS) 처리하기



하지만 프로젝트 전체를 처리할려고 하면... 이과같은 방법은 맞지 않다고 생각되네요.


시간이 지난만큼 더 발전된 모습이겠죠?


프로젝트 전체를 공통적으로 크로스사이트 스크립트를 처리하기위해

스프링의 filter chain을 사용하였습니다.


지금부터 제가 사용한 방법을 차례로 기재하겠습니다.


1.web.xml 등록하기



		xssfilter
		lee.comm.util.CrossScriptingFilter
	
	
		xssfilter
		/*
	

filter의 이름을 xssfilter라 정의하고
클래스를 정해 주었습니다.

그리고 filter-mapping으로
적용할 url pattern을 기재하였습니다.
저는 공통적으로 처리할 예정이기 때문이 /*로 기재하였습니다.

2. CrossScriptingFilter 클래스 만들기


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 CrossScriptingFilter implements Filter {
	
	public FilterConfig filterConfig;
	
    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 RequestWrapper((HttpServletRequest) request), response);
 
    }

FilterConfig를 정의하고 
doFilter 메소드를 활용하여 실행될 클래스
RequestWrapper를 적어 주었습니다.

3. RequestWrapper 클래스 만들기


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestWrapper extends HttpServletRequestWrapper {

	 public RequestWrapper(HttpServletRequest servletRequest) {
	        super(servletRequest);
	    }
	 
	    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] = cleanXSS(values[i]);
	       }
	      return encodedValues;
	    }
	 
	    public String getParameter(String parameter) {
	          String value = super.getParameter(parameter);
	          if (value == null) {
	                 return null;
	                  }
	          return cleanXSS(value);
	    }
	 
	    public String getHeader(String name) {
	        String value = super.getHeader(name);
	        if (value == null)
	            return null;
	        return cleanXSS(value);
	 
	    }
	 
	    private String cleanXSS(String value) {

	        value = value.replaceAll("eval\\((.*)\\)", "");
	        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
	        return value;
	    }

}

제가 직접 사용하고 있는 소스는 아래의 그림과 같습니다.
소스를 기재하니깐 에디터에서 스크립트 언어를 잡아먹어 깨지더라고요..


기본적인 script, javascript 태그를 제외하고

문제가 될만한 태그들을 다 치환해주었어요.


헤더와 파라미터들의 값들을 필터링 해주는 효과가 나타나게 됩니다.

encodedValues 라던지, claeanXSS의 value 부분에 로그 등을 찍어 데이터 확인이 가능합니다.


특이사항

데이터를 주고 받기위해 html, jsp에서 form 태그를 사용합니다.
그중에 첨부파일을 사용하고자 하는경우에는 enctype="multipart/form-data"
설정을 적어줍니다.

하지만 enctype="multipart/form-data" 설정이 기재되어 있는 태그는
filter를 타지 않습니다.
찾아보니 enctype="multipart/form-data" 를 사용한 form 의 데이터도 filter를 타게 할수 있었습니다.

하지만 저는 게시판에 html 태그를 사용하기 때문에 view 단에서 jstl인 <c:out value=""/>를 사용하였습니다.

기본적인 form 태그에는 filter로 사용하여
Fiddler 등에서 파라미터 변조를 통해 스크립트가 실행되는것을 방지하였고
일반 게시판에서는 jstl을 사용하였습니다.


질문 주시면 제가 아는한 답변 드리겠습니다.

감사합니다.

좋은하루 보내세요.