본문 바로가기

오픈소스/스프링

[Spring] XSS Filter 적용

 

 XSS(Cross Site Scripting)에 대해 다들 아실거라고 생각합니다. 서버로 보내는 폼이나 데이터 안에 스트링형태의 자바스크립트를 보내 개발자가 의도한 코드와는 다르게 코드가 동작하여 주로 사용자의 데이터를 가져가거나 악성코드를 심는 행위를 말하는 것입니다. 아래 그림을 보시면서 예를 들어보도록 하겠습니다.

 

 

 

 위 그림을 간단하게 설명하겠습니다. 어느 특정 웹페이지에 입력 폼이 있다고 합시다. 그 특정 웹페이지를 구글로 들어서 설명하겠습니다. 구글에 검색 폼 안에 스크립트를 넣고 검색버튼을 누르면 구글 개발자에 의도와는 다르게 스크립트가 실행되어 어떠한 정보를 변경하거나 탈취하는 코드를 작성하고 실행시키면 동작되는 것이죠.

 

 스프링에서는 필터를 적용하여 XSS공격을 방어할 수 있습니다. 본 문서에서는 XSS 공격을 방어하기 위한 코드 및 예제입니다.

 

 

# Contents


  • XSS Filter 적용

 

 

# XSS Filter 적용


먼저 자바코드를 추가할 예정입니다. 저는 추가할 자바코드의 패키지 명을 com.mycom.myapp.filter 로 하겠습니다.

그리고 자바 파일명을 CrossScriptingFilter.java로 만들었습니다. 밑에 사진은 방금 했던 사진의 예시입니다.

 

 

 

그리고 아래 코드를 복사 붙여넣기 합니다.

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);
	
	   }

}

 

필터에 적용될 RequestWrapper를 생성하여 작성합니다.

생성할 패키지 위치는 편한데 넣으시고, 자바 파일명은 RequestWrapper.java 입니다. 아래는 사진 및 코드입니다.

 

 

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
 
public final 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) {
    	System.out.println("XSS Filter before : " + value);
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        value = value.replaceAll("'", "& #39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        value = value.replaceAll("script", "");
        System.out.println("XSS Filter after : " + value);
        return value;
    }
}

 

 

 web.xml 로 이동합니다.

 web.xml의 경로는 "My Project\src\main\webapp\WEB-INF\web.xml" 이며 아래는 이클립스로 접근한 사진입니다.

 

 

 

xml파일을 열어서 아래 코드를 넣어주세요. 

<!-- XSS 처리 -->
<filter>
	<filter-name>XSS</filter-name>
    <filter-class>com.mycom.myapp.filter.CrossScriptingFilter</filter-class> // 자신의 CrossScriptingFilter 적용 위치
</filter>
<filter-mapping>
    <filter-name>XSS</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

서버를 다시 시작해주면 XSS 필터 적용이 완료됩니다.

이렇게 간단하게 XSS필터를 적용하는 방안에 대해 알아봤습니다. 

좋은 기능을 개발하는 방법도 좋지만 기능을 개발하기 전 공격에 대한 방어도 생각하는 면도 있어야 한다고 생각합니다.