Skip to content

XSS(Cross Site Scripting)

Doyoung Lee edited this page Jan 3, 2025 · 4 revisions

문제 상황

현재 textarea를 사용하고, input 데이터를 서버 전송 하고 그리고 이를 브라우저에 출력하는 과정에서 문제가 생겼다. 그것은 내용이 태그까지 포함이 되어 출력이 되는 것이다. image
이것이 출력되는 이유는 {} 내부의 값이 HTML 코드가 포함된 문자열인 경우 HTML 태그를 인코딩해서 처리하므로, 브라우저에는 태그가 그대로 보인다. 이러한 이유로 태그가 보이는 것인데, 단순 태그가 보이는 것이 문제가 아닌 보안상의 문제가 생길수 있다. 이는 XSS 공격이라고 하는데, XSS(Cross Site Scripting)같은 공격이 있다. 이것은 게시판이나, 웹 메일 등에 자바 스크립트와 같은 스크립트 코드를 삽입 해 개발자가 고려하지 않은 기능이 작동하게 하는 치명적일수 있는 공격이다. 또한 대부분의 웹 해킹 공격 기법과는 달리 클라이언트 즉, 사용자를 대상으로 한 공격이다.

해결

그래서 이를 방지하기 위해 여러가지 방법이 있는데, 처음은 dangerouslySetInnerHTML 속성을 사용하여 HTML 태그를 인코딩하지 않는다. 이게 완벽하지 않은 이유가, 문자열을 HTML로 렌더링할 수 있게 하여, 외부 데이터가 포함된 경우 XSS 공격에 매우 취약하다. 악성 코드가 포함된 HTML이나 스크립트를 실행할 위험이 있다. 그래서 여기에 추가한 방법이 라이브러리 설치를 한 것이다. DOMPurify라는 라이브를 다운 받아 사용하는 것인데, 이는 한번 리액트에서 dangerouslySetInnerHTML를 사용할 때, 외부 데이터가 포함된 경우 DOMPurify를 통해 데이터를 정제한 후 렌더링함으로써 보안 문제를 줄일 수 있다.

  import DOMPurify from "dompurify";
  1. 위와 같이 import를 하고 설치를 해야한다. npm install dompurify를 해야한다.
  2. 보안이 필요한 부분을 sanitize 메서드에 전달한다. 그리고 변수가 필요한 경우 아래와 같이 변수에 할당한다.
const sanitizedContent = DOMPurify.sanitize(`${data?.item.content}`);
  1. 그리고 사용하고자 하는 곳에 아래와 같이 입력한다. __html:의 뒷부분에 아까 변수를 넣어준다.
 <span dangerouslySetInnerHTML={{__html: sanitizedContent,}}></span>

와 같이 사용하면 된다.

완성!

image

Clone this wiki locally