본문 바로가기
Spring

XSS 공격 방지를 위한 필수 도구 Jsoup clean 사용법과 예시

by 흑시바 2024. 9. 24.

웹 애플리케이션을 개발할 때, 보안은 항상 최우선 과제 중 하나이다. 특히, 크로스 사이트 스크립팅(XSS) 공격은 매우 흔한 보안 취약점 중 하나로, 이를 방지하기 위한 적절한 조치가 필요하다.

 

Jsoup은 Java 기반의 HTML 파싱 라이브러리로, HTML 문서에서 데이터를 추출하거나 HTML을 조작하는 데 유용하다. 특히, Jsoup의 clean() 메서드는 HTML 문서에서 악성 스크립트나 불필요한 태그를 제거하여 안전한 HTML을 생성하는 데 사용된다. 해당 포스트에서는 Jsoup의 clean() 메서드 사용법과 Spring 기반 환경에서의 활용 예시에 대해 상세히 설명한다.

XSS란 무엇인가?

XSS(Cross-Site Scripting)는 공격자가 악성 스크립트를 웹 페이지에 삽입하여 다른 사용자가 해당 페이지를 방문할 때 스크립트가 실행되도록 하는 공격 기법이다. 이를 통해 공격자는 사용자의 세션을 탈취하거나, 악성 코드를 실행하거나, 민감한 정보를 탈취할 수 있다.

Jsoup clean() 메서드 사용법

clean() 메서드는 HTML 문자열과 허용할 태그 및 속성을 정의하는 Safelist 객체를 인자로 받아, 지정된 규칙에 따라 HTML을 정리(clean)한다. 기본적인 사용법은 다음과 같다.

 

String safeHtml = Jsoup.clean(unsafeHtml, Safelist.basic());

 

여기서 unsafeHtml은 정리할 HTML 문자열이고, Safelist.basic()은 기본적으로 허용할 태그와 속성을 정의한 Safelist이다. Jsoup은 여러 가지 기본 Safelist를 제공하며, 필요에 따라 커스터마이징 할 수도 있다.

 

Safelist.none() 모든 태그와 속성을 제거한다.
Safelist.simpleText() 텍스트와 기본적인 텍스트 포맷팅 태그만 허용한다.
Safelist.basic() 기본적인 HTML 태그와 속성을 허용한다.
Safelist.basicWithImages() 기본적인 HTML 태그와 속성에 이미지 태그를 추가로 허용한다.
Safelist.relaxed() 상대적으로 많은 태그와 속성을 허용한다.

기본 제공 Safelist 외에도, 필요에 따라 커스터마이징 된 Safelist를 생성할 수 있다. 예를 들어, 특정 태그와 속성만 허용하는 Safelist를 생성하려면 다음과 같이 한다.

 

 Safelist customSafelist = new Safelist()
.addTags("a", "b", "p")
.addAttributes("a", "href")
.addProtocols("a", "href", "http", "https");

String safeHtml = Jsoup.clean(unsafeHtml, customSafelist);

 

위 예제에서는 a, b, p 태그와 a 태그의 href 속성만 허용하고, href 속성의 값으로는 http와 https 프로토콜만 허용하도록 Safelist를 커스터마이징하였다.

Safelist()

Safelist 클래스는 다양한 메서드를 제공하여 허용할 태그와 속성을 세부적으로 설정할 수 있다.

 

addTags(String... tags)

- 허용할 태그를 추가한다.


addAttributes(String tag, String... attributes)

- 특정 태그에 대해 허용할 속성을 추가한다.


addEnforcedAttribute(String tag, String attribute, String value)

- 특정 태그에 대해 강제할 속성을 추가한다.


addProtocols(String tag, String attribute, String... protocols)

- 특정 태그와 속성에 대해 허용할 프로토콜을 추가한다.


removeTags(String... tags)

- 허용 목록에서 태그를 제거한다.


removeAttributes(String tag, String... attributes)

- 특정 태그에 대해 허용 목록에서 속성을 제거한다.

Spring 기반 환경에서의 활용 예시

Spring 기반의 웹 애플리케이션에서 Jsoup을 활용하여 사용자 입력을 정리하는 예제를 살펴보자. 예를 들어, 사용자가 입력한 댓글을 저장하기 전에 악성 스크립트를 제거하는 기능을 구현할 수 있다.

컨트롤러 작성

@RestController
public class ShibaController {

    @PostMapping("/sanitizeInput")
    public String sanitizeInput(@RequestBody String userInput) {
        return Jsoup.clean(userInput, Safelist.basic());
    }
}

 

위 예시에서, 사용자가 입력한 데이터를 @RequestBody로 받아 Jsop.clean() 메서드를 사용하여 필터링한 후 반환한다.

공격 시나리오

이제 실제로 XSS 공격을 시도하는 예시를 보겠다. 다음과 같은 HTML 폼이 있다고 가정하자.

 

<!DOCTYPE html>
<html>
<head>
    <title>XSS Test</title>
</head>
<body>
    <form action="/sanitizeInput" method="post">
        <label for="input">Enter some text:</label>
        <input type="text" id="input" name="input">
        <button type="submit">Submit</button>
    </form>
</body>
</html>

 

사용자가 입력 필드에 다음과 같은 악성 스크립트를 입력한다고 가정하자.

 

<script>alert('XSS Attack!');</script>

 

이 입력이 서버로 전송되면, Jsoup.clean() 메서드가 이를 필터링하여 안전한 형태로 변환한다. 변환된 결과는 다음과 같다.

 

&lt;script&gt;alert('XSS Attack!');&lt;/script&gt;

 

이제 브라우저에서 이 결과를 렌더링하면, 스크립트가 실행되지 않고 단순한 텍스트로 표시된다.

 

이와 같이, Jsoup의 clean() 메서드를 사용하여 Spring 기반의 웹 애플리케이션에서 사용자 입력을 안전하게 처리할 수 있다. 이를 통해 XSS 공격을 방지하고, 애플리케이션의 보안을 강화할 수 있다. HTML 태그를 직접 받아야 하는 경우가 생긴다면 반드시 Jsoup clean()을 이용한 필터링 과정을 거쳐서 개발하도록 하자.

REFERENCE

https://jsoup.org/cookbook/cleaning-html/safelist-sanitizer

https://jsoup.org/apidocs/org/jsoup/safety/Safelist.html

댓글