quill editor와 xss

Yi Kanghoon·2023년 1월 1일
1

개요

게시글 작성 기능을 위해 react-quill을 도입하면서 html 태그를 포함한 스트링을 그대로 저장하고 그대로 보여주면 될 것...이라고 생각했지만 일반적인 방법으로 작동하지 않음

dangerouslySetInnerHTML

원래 계획은

return(
	<div>{data?.content}</div>
)

와 같이 작성하여 스트링에 포함된 태그는 태그대로, 내용은 내용대로 보여지길 원했지만, 실제로는

	<p>내용을 작성합니다. 이것은 본문입니다.</p></br>

와 같이 태그가 기능하지 않고 단순히 스트링으로 출력됨.

원하는 대로 기능하게 하기 위해 찾아본 결과 react에서는 DOM element에 innerHTML을 사용하려면 아래와 같이 조금 다른 방식을 이용해야 함을 알 수 있었음.

<div dangerouslySetInnerHTML={{ __html: String(data?.content || "loading") }} />

dangerously......?

innerHTML을 사용하기 위한 방법을 찾으면서 코드에서 HTML을 설정하는 것이 주요한 보안 위협 또한 유발할 수 있음을 알게 됨.

Cross Site Scripting (XSS)

(모교 학생들이 쓸 서비스이긴 하지만 혹시 모르잖아?)
게시글을 작성...하는 척 게시글에 악성스크립트를 주입하는 방식으로, 이전에 살짝 공부했던 SQL injection과도 공격의 시작점이 동일하지 않나 생각된다.

프론트엔드에 주입하면 XSS, 백엔드에 주입하면 SQL injection...?

여튼, 따로 방어를 하지 않는다면 게시글에

<a href="javascript:alert('XSS')">XSS</a>

와 같은 태그를 삽입하여 원하는 동작을 실행할 수 있다.

방어하기

일단 내가 사용한 방법은 악성 스크립트를 필터링하여 반환하는 라이브러리(dompurify)를 사용하는 것이었다. 사용방법으로는 맨 위의 dangeouslySetInnerHTML을 사용할 때 속성 값을 dompurify.sanitize로 감싸주는 것으로,

<div dangerouslySetInnerHTML={{ __html: dompurify.sanitize(String(data?.content || "loading")) }} />

와 같이 사용하면 악성 스크립트를 필터링한 값을 출력하도록 할 수 있다.

입력 필터링....?

사실 지금은 일단 입력을 받고 출력할 때 필터링하는 방식이라 SQL injection에 대한 방어도 부족하고, 한계점이 있을 것 같다. 입력부에서 필터링하는 방법도 더 알아보고 프로덕션 배포 이전에 적용할 필요가 있겠다.

profile
Full 'Snack' Developer

0개의 댓글