프로그래밍/spring

위지윅 에디터와 XSS 대응 방법 with 타임리프

승민아 2024. 7. 29. 17:32

프로젝트에 위지윅 에디터를 사용하기위해 CKEditor 오픈소스를 적용했다.

 

사용자가 굵은 글씨, 기울임 등 에디터를 통해 작성한 내용을 서버에서 저장하기위해서는

태그를 함께 저장해야한다.

 

태그를 함께 저장해야할텐데 XSS 공격은 어떻게 대응할까?

 

동작 예시를 통해 대응 방법을 이해해보자.

 

사용자가 의도적으로 굵은 글씨를 표현하는 태그인 <strong> 태그를 다음과 같이 삽입했다고 하자.

태그 삽입

 

 

에디터를 통해 서버로 넘어와 저장되는 값은 다음과 같다.

서버에 저장된 값

 

'<' 글자가 "&lt;"로 저장되었다.

 

html에서 <, >, & 는 같은 특수한 기능을하는 문자들이므로

서버에서는 안전한 문자로 저장할 필요가 있기에 변환하여 저장한 것이다.

 

에디터의 굵은 글씨 사용

그러면 의도적으로 태그를 삽입하는것이 아닌

에디터를 통해서 굵은 글씨를 작성해보자.

 

서버에는 어떻게 저장이 될까?

서버 저장 결과

 

DB에는 '<' 문자가 안전하게 변환되지 않고 '<' 문자 그대로 저장되었다.

그렇다. 라이브러리에서는 XSS를 방지하고자

에디터를 통한 태그만 '<' 문자 그대로 서버에 전송하는 것이다.

 

 

content

 <p><strong>strong</strong></p>

타임리프 th:text를 통해 위의 content를 출력해보자.

 

타임리프 th:text

<div th:text="${poster.content}"></div>

 

 

th:text 출력 결과

텍스트 그대로 출력이 된다. 정상적인 태그 삽입인 에디터를 통해서 <strong> 태그를 잘 넣었는데

태그를 문자 그대로 출력해버리는 것이다.

 

타임리프는 문자 그대로 출력하지 않고 태그를 읽어 출력하는 "th:utext"를 제공한다.

 

타임리프 th:utext

<div th:utext="${poster.content}"></div>

 

th:utext 출력 결과

 

html 결과

태그가 적용되어 굵은 글씨로 표현된다.

 

html에서 <, >, &와 같은 특수문자를 변환하는것을 이스케이프라고 한다.

th:text는 이스케이프를 적용해서 문자 그대로를 출력하여 특수 기능은 동작하지 않게한다.

th:utext는 unescape이다. 특수 기능이 동작하게 렌더링한다.

 

정리

위지윅 에디터는 악의적인 태그 입력을 방지하는 기능을 포함하고 있다.

그래서 서버로 전송할때 정상적인 태그는 그대로 전달하지만

악의적인 태그는 이스케이프가 적용되어 변환되어 전달한다.

 

서버에서는 이 전송되는 데이터를 그대로 저장한다고 가정하자.

 

타임리프를 통해 서버에 저장된 데이터를 읽을때

이스케이프를 고려하여 읽음으로써 XSS를 방지할 수 있다.

 

th:text를 통해 서버에 저장된 문자열 그대로 출력할 수 있지만

th:utext를 통해 이스케이프 문자를 구분하여 태그로쓸지말지를 파악해서 출력한다.