[Spring] lucy-xss-servlet-filter를 사용하여 XSS 공격 방어하기(1)

hyewon jeong·2024년 7월 5일
0

Spring

목록 보기
65/65

🎈 1. lucy-xss-servlet-filter를 적용한 이유

아래 글은 lucy-xss-servlet-filter에서 참고하여적용한 글입니다.

📍 1-1. lucy-xss-filter의 한계

  • 필요한 곳에 XSS 방어코드 누락
  • 불필요한 곳에 XSS 방어코드가 적용되는 경우
  • 여기저기 XSS 방어코드가 혼재되어 유지보수 비용 증가

Lucy-Xss-Servlet-Filter는 웹어플리케이션으로 들어오는 모든 요청 파라메터에 대해 기본적으로 XSS 방어 필터링을 수행하며 아래와 같은 필터링을 제외할 수 있는 효과적인 설정을 제공합니다.

  • 설정한 url 필터링 제외
  • 설정한 prefix로 시작하는 파라메터 필터링 제외
  • 설정한 파라메터 필터링 제외

📍 1-2.Lucy-Xss-Servlet-Filter 장점

  • XML 설정 만으로 XSS 방어가 가능해짐
  • 비지니스 레이어의 코드 수정이 발생하지 않음
  • 개발자가 XSS 방어를 신경 쓰지 않아도 됨
  • XSS 방어가 누락되지 않음
  • 설정 파일 하나로 XSS 방어절차가 파악됨

📍 1-3.Lucy-Xss-Servlet-Filter 단점

  • 파라메터명에 대해 관리가 필요해짐
  • 일괄 적용되어 영향 받기 때문에 정확한 필터링 룰 정의가 중요함

🎈 2. Lucy-Xss-Servlet-Filter 적용 방법

📍 2-1. Pom.xml 에 라이브 러리 추가

<dependency>
	<groupId>com.navercorp.lucy</groupId>
	<artifactId>lucy-xss-servlet</artifactId>
	<version>2.0.0</version>
</dependency>

📍 2-2. web.xml 설정

...
<!-- xssEscapeServletFilter는 CharacterEncodingFilter 뒤에 위치해야 한다. -->
<filter>
	<filter-name>encodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
	<filter-name>xssEscapeServletFilter</filter-name>
	<filter-class>com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>xssEscapeServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
...

📍 2-3. webapp>resources 파일 내에 lucy-xss-servlet-filter-rule.xml 파일 생성 및 lucy-xss-servlet-filter-rule.xml 필터링 룰 작성

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://www.navercorp.com/lucy-xss-servlet">
    <defenders>
        <!-- XssPreventer 등록 -->
        <defender>
            <name>xssPreventerDefender</name>
            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssPreventerDefender</class>
        </defender>

        <!-- XssSaxFilter 등록 -->
        <defender>
            <name>xssSaxFilterDefender</name>
            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssSaxFilterDefender</class>
            <init-param>
                <param-value>lucy-xss-sax.xml</param-value>   <!-- lucy-xss-filter의 sax용 설정파일 -->
                <param-value>false</param-value>        <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->
            </init-param>
        </defender>

        <!-- XssFilter 등록 -->
        <defender>
            <name>xssFilterDefender</name>
            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssFilterDefender</class>
            <init-param>
                <param-value>lucy-xss.xml</param-value>    <!-- lucy-xss-filter의 dom용 설정파일 -->
                <param-value>false</param-value>         <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->
            </init-param>
        </defender>
    </defenders>

    <!-- default defender 선언, 별다른 defender 선언이 없으면 default defender를 사용해 필터링 한다. -->
    <default>
        <defender>xssSaxFilterDefender</defender>
    </default>

    <!-- global 필터링 룰 선언 -->
    <global>
        <!-- 모든 url에서 들어오는 globalParameter 파라메터는 필터링 되지 않으며
                또한 globalPrefixParameter로 시작하는 파라메터도 필터링 되지 않는다. -->
        <params>
            <param name="globalParameter" useDefender="false" />
            <param name="globalPrefixParameter" usePrefix="true" useDefender="false" />
        </params>
    </global>

<!--    &lt;!&ndash; url 별 필터링 룰 선언 &ndash;&gt;-->
<!--    <url-rule-set>-->

<!--        &lt;!&ndash; url disable이 true이면 지정한 url 내의 모든 파라메터는 필터링 되지 않는다. &ndash;&gt;-->
<!--        <url-rule>-->
<!--            <url disable="true">/disableUrl1.do</url>-->
<!--        </url-rule>-->

<!--        &lt;!&ndash; url1 내의 url1Parameter는 필터링 되지 않으며 또한 url1PrefixParameter로 시작하는 파라메터도 필터링 되지 않는다. &ndash;&gt;-->
<!--        <url-rule>-->
<!--            <url>/url1.do</url>-->
<!--            <params>-->
<!--                <param name="url1Parameter" useDefender="false" />-->
<!--                <param name="url1PrefixParameter" usePrefix="true" useDefender="false" />-->
<!--            </params>-->
<!--        </url-rule>-->

<!--        &lt;!&ndash; url2 내의 url2Parameter1만 필터링 되지 않으며 url2Parameter2는 xssSaxFilterDefender를 사용해 필터링 한다.  &ndash;&gt;-->
<!--        <url-rule>-->
<!--            <url>/url2.do</url>-->
<!--            <params>-->
<!--                <param name="url2Parameter1" useDefender="false" />-->
<!--                <param name="url2Parameter2">-->
<!--                    <defender>xssSaxFilterDefender</defender>-->
<!--                </param>-->
<!--            </params>-->
<!--        </url-rule>-->
<!--    </url-rule-set>-->
</config>

🎈 3. 결과

<script>alert("dk");</script>

를 요청하고 조회 하면 아래와 같이 조회 된다.

&lt;script&gt;alert("dk");&lt;/script&gt;
  • 처음에는 직접 filter를 정의하여 사용해봤지만 실수하는 부분이 생기기도 해서 lucy-xss-servlet-filter 적용해봤습니다.
    html특수문자에 대해 이스케이프 처리가 잘 되어 편하긴 했지만
    적용 하고 나서야 안 사실이 있습니다. ㅠㅠ

    그 처리가 form-data에 대해서만 적용되고 Request Raw Body로 넘어가는 JSON에 대해서는 처리해주지 않는다는 단점이 있습니다.
    그래서 JSON을 주고 받는 API 서버의 경우에는 직접 처리를 해주는 방법을 다음 번에 시도 하겠습니다.

Spring에서 json XSS 공격 방어하기 (2)(maven)

profile
개발자꿈나무

0개의 댓글