summernote와 XssServletFilter 적용하기

sarah·2022년 12월 17일
0

xss

목록 보기
3/3
💡 스프링 프로젝트를 진행하며 xss 공격 방어를 위해 lucy-xss-servlet-filter를 적용하였다. 그리고 게시판을 만들때 summernote란 에디터를 사용하며, lucy-xss-servlet-filter를 이에 맞춰 추가적으로 커스텀하고 적용해보겠다.

기존에 적용하던 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>
    </defenders>

    <!-- default defender 선언, 필터링 시 지정한 defender가 없으면 여기 정의된 default defender를 사용해 필터링 한다. -->
    <default>
        <defender>xssPreventerDefender</defender>
    </default>
</config>
  • defuault defenderXssPreventerDefender를 사용했다.
  • 그러나 summernote를 사용하게 되면서, 해당 데이터는 html 그대로 저장하고 싶었다. 그리고 추가적으로 script 태그를 제거하고 싶었다. 이에 맞춰 lucy-xss-servlet-filter-rule.xml을 수정해보겠다.

변경한 lucy-xss-servlet-filter-rule.xml

요구사항

  1. 특정 url의 parameter에 XssSaxFilterDefender를 적용시키기
  2. lucy-xss-sax.xml 설정파일에서 기존 html 태그는 유지하되, script 태그는 제거하기
<?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>
    </defenders>

    <!-- default defender 선언, 필터링 시 지정한 defender가 없으면 여기 정의된 default defender를 사용해 필터링 한다. -->
    <default>
        <defender>xssPreventerDefender</defender>
    </default>

    <!-- url 별 필터링 룰 선언 -->
    <url-rule-set>
        <!-- url 내의 contents만 필터링 되지 않으며 xssSaxFilterDefender를 사용해 필터링 한다.  -->
        <url-rule>
            <url>/url.do</url>
            <params>
                <param name="contents" useDefender="false">
                    <defender>xssSaxFilterDefender</defender>
                </param>
            </params>
        </url-rule>
    </url-rule-set>
</config>

⇒ 기존의 xssPreventerDefender를 적용하되, 특정 url의 특정파라미터에만 xssSaxFilterDefender 적용하도록 변경하였다.

추가한 lucy-xss-sax.xml

  • resource 아래에 lucy-xss-sax.xml을 생성해준다.
  • lucy-xss-default-sax.xml 을 extends 한다.
    (git에 올라온 파일에는 extends 하는 파일은 lucy-xss-superset-sax.xml 파일인데, 해당 설정을 사용하지 않을거라 변경하였다.)
  • lucy-xss-default-sax.xml 은 HTML 4.0을 기본으로 하며, HTML 5.0과 Internet Explorer에 특화된 몇 가지 명세를 추가한 기본 설정 파일로, 선언된 요소들은 필터링 되지 않는다.(disable 생략되어 있음)
  • script 태그를 추가하여 removeTag로 지정하였다.
<?xml version="1.0" encoding="UTF-8"?>

<config xmlns="http://www.nhncorp.com/lucy-xss"
	extends="lucy-xss-default-sax.xml">
	<elementRule>
		<element name="script" removeTag="true" />
	</elementRule>
</config>

summernote 에디터를 사용해서 저장하기

  • summernote 에 “내용” 을 입력하고 저장 하기 전에 console.log()를 찍어보면 기본적으로 summernote 가 p태그를 붙여서 저장해준다.

  • 그런데 summernote에 직접 태그를 입력하면 summertnote가 자체적으로 escape처리한다.
  • escape 처리 된 태그는 lucy-xss-servlet-filter에서 걸러지지 않기 때문에, 화면 단에서 저장 전에 unescape 시켜서 서블릿으로 보내야 filter가 생각한대로 작동한다.

서블릿으로 데이터를 보내기전 unescape 시키기

  • lodash 라이브러리 사용하기
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script>
	...
	let contents = $("#contents").val();
	console.log(contents);
	let unescapedContents = _.unescape(contents);
	console.log(unescapedContents);
	...
<script>

⇒ 이렇게 서블릿을 보내기 전 summernote가 escape 시킨 데이터를 unescape 시켜주면, lucy-xss-servlet-filter가 잘 작동한다.

0개의 댓글