본문 바로가기
프로그래밍/자바

Jsoup을 사용한 화이트 리스트 방식의 XSS(Cross-Site Script)공격 방어

by pentode 2019. 2. 26.

웹 페이지에서 CKEditor 와 같은 HTML에디터를 이용해서 데이터를 입력받아 보여줄때 고려해야 할것으로 XSS(Cross-Site Script)공격이 있습니다.


글을 작성하는 사용자가 HTML을 사용할 수 있도록 허용하게 되면 자바스크립트도 사용할 수 있게 되므로 XSS공격을 쉽게 할 수 있는 환경이 됩니다.


HTML코드에서 자바스크립트를 실행할 수 있는 방법은 수도 없이 많으므로 <script> 태그와 같은 지정된 특정 패턴을 걸러내는 블랙리스트 방식으로는 XSS를 막기가 힘듭니다.


Jsoup 라이브러리는 HTML 문서에서 지정된 태그와 속성만이 통과하고 나머지는 제거하는 화이트 리스트 방식의 XSS 방지 기능을 제공합니다.


여기에서는 Jsoup을 사용해서 화이트 리스트 방식의  HTML 문서 필터링 방법을 알아봅니다.


Jsoup의 설치 및 HTML Parser로써의 사용법은 "jsoup : 자바 HTML 파서(Java HTML Parser)"를 참조하세요.



1. 미리 만들어져 있는 화이트 리스트를 사용하는 방법


-  Whitelist.basic()


String htmlDoc = "<p>TEST</p>"

+ "<script>alert('test');</script>"

+ "<img src='/test.jpg' onerror='alert(\"test\");' />";


String safeDoc = Jsoup.clean(htmlDoc, Whitelist.basic());


System.out.println(safeDoc);


결과)

<p>TEST</p>



화이트 리스트의 basic() 메소드에서는 다음 태그와 속성을 허용합니다.


public static Whitelist basic() {

    return new Whitelist()

      .addTags(

              "a", "b", "blockquote", "br", "cite", "code", "dd", "dl", "dt", "em",

              "i", "li", "ol", "p", "pre", "q", "small", "span", "strike", "strong", "sub",

              "sup", "u", "ul")


      .addAttributes("a", "href")

      .addAttributes("blockquote", "cite")

      .addAttributes("q", "cite")


      .addProtocols("a", "href", "ftp", "http", "https", "mailto")

      .addProtocols("blockquote", "cite", "http", "https")

      .addProtocols("cite", "cite", "http", "https")


      .addEnforcedAttribute("a", "rel", "nofollow")

      ;

}



- Whitelist.basicWithImages()


결과)

<p>TEST</p>

<img>


화이트 리스트의 basicWithImages() 메소드에서는 basic()에 추가로 다음 태그와 속성을 허용합니다.


public static Whitelist basicWithImages() {

    return basic()

        .addTags("img")

        .addAttributes("img", "align", "alt", "height", "src", "title", "width")

        .addProtocols("img", "src", "http", "https")

        ;

}



- Whitelist.relaxed()


화이트 리스트의 relaxed() 메소드에서는 다음 태그와 속성을 허용합니다.


public static Whitelist relaxed() {

    return new Whitelist()

        .addTags(

                "a", "b", "blockquote", "br", "caption", "cite", "code", "col",

                "colgroup", "dd", "div", "dl", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6",

                "i", "img", "li", "ol", "p", "pre", "q", "small", "span", "strike", "strong",

                "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "u",

                "ul")


        .addAttributes("a", "href", "title")

        .addAttributes("blockquote", "cite")

        .addAttributes("col", "span", "width")

        .addAttributes("colgroup", "span", "width")

        .addAttributes("img", "align", "alt", "height", "src", "title", "width")

        .addAttributes("ol", "start", "type")

        .addAttributes("q", "cite")

        .addAttributes("table", "summary", "width")

        .addAttributes("td", "abbr", "axis", "colspan", "rowspan", "width")

        .addAttributes("th", "abbr", "axis", "colspan", "rowspan", "scope", "width")

        .addAttributes("ul", "type")


        .addProtocols("a", "href", "ftp", "http", "https", "mailto")

        .addProtocols("blockquote", "cite", "http", "https")

        .addProtocols("cite", "cite", "http", "https")

        .addProtocols("img", "src", "http", "https")

        .addProtocols("q", "cite", "http", "https")

        ;

}



- Whitelist.simpleText()


아래 태그만 허용합니다.


public static Whitelist simpleText() {

    return new Whitelist()

        .addTags("b", "em", "i", "strong", "u")

        ;

}



- Whitelist.none()


텍스트 외의 모든 태그를 제거합니다.



2. 이미지를 허용시 src 속성이 사라지는 현상 해결


허용 태그에 img 가 있지만 실행결과에는 src 속성이 사라지는 것을 볼 수 있습니다. src, href 등 속성에

상대주소를 허용하여 주어야 합니다.


String safeDoc = Jsoup.clean(htmlDoc

, "http://localhost"

, Whitelist.relaxed().preserveRelativeLinks(true));


실행결과)

<p>TEST</p>

<img src="/test.jpg">


Jsoup.clean() 메소드의 두번째 인자로 baseUri를 지정하고, Whitelist에 preserveRelativeLinks(true)로 설정합니다.



3. 개행 문자 보존하기


기본적으로 텍스트에 있는 개행문자를 제거해버립니다. 이것을 보존하기 위해서 다음 옵션을 사용합니다.


String safeDoc = Jsoup.clean(htmlDoc

, "http://localhost"

, Whitelist.relaxed().preserveRelativeLinks(true)

, new Document.OutputSettings().prettyPrint(false));



4. Whitelist에 태그 와 속성 추가하기


Whitelist객체의  basic() 함수나 relaxed()함수를 참조하여 태그나 속성을 추가할 수 있습니다.


- basic()에 img와 div 태그와 속성 추가하기


Whitelist.basic()

.addTags("img", "div")

.addAttributes("img", "align", "alt", "height", "src", "title", "width")

.addAttributes("div", "class")

.addProtocols("img", "src", "http", "https");



이처럼 기본적으로 제공되는 Whitelist 객체에 원하는 태그를 추가할 수도 있고 처음부터 Whitelist 객체를 직접 만들 수도 있습니다.



반응형