[HTML, CSS] Insert Text with Line Break (feat. XSS)

SUNG JE KIM·2023년 1월 5일
2
post-thumbnail

결론

  • dangerouslySetInnerHTML 또는
    html-react-parser의 HtmlParser를 사용할 땐 XSS를 고려해야 한다.
  • 상황이 따라주지 않을 땐, 위와 같은 방법보단 HTML 또는 CSS를 이용하는 것이 좋은 선택이다.

진행한 프로젝트에서 마주친 수많은 이슈 중에서,
\n이 포함되어 있는 string을 element 안에 넣어야 할 때 마주친 이슈들을 정리한 것이다.


Element 안에 Text 넣기


위와 같은 코드를 작성하고 browser에서 확인해보니 아래와 같았다.

결과

그래서 정규표현식을 통해서 \n 을 <br />로 바꿔, dangerouslySetInnerHTML
또는 html-react-parser의 HtmlParser를 이용해 삽입을 해야겠다는 생각이 들었다.


\n 을 <br />로 변환

Parents

DangerousBox

HtmlParserBox

결과

굉장히 효과적이였다? 라고 생각했다. 악성 사용자를 만나기 전까진....


문제의 발생

악성 사용자의 코드 삽입

  • DangerousBox와 HtmlParserBox 코드는 두번째 예시와 같습니다.

결과

\n을 <br />로 변경하고 그것을 dangerouslySetInnerHTML 또는 HtmlParser를 사용한 곳에 넘겨주고 있는 상황이다. 근데 사용자가 악성 script를 작성하였더니, alert가 뜨게 되는 모습을 보게 되었다.

\n을 <br />로 변경하는 방법은 오히려 더 좋지 않는 것이라고 판단을 하였다.
\n 때문에 머리가 아팠는데, 아래와 같은 CSS 키워드를 사용해보았다.

white-space: pre-wrap;
word-wrap: break-word;
  • white-space : 요소 내부의 공백을 처리하는 방법을 설정 합니다.
  • word-wrap : 텍스트가 자신의 콘텐츠 박스 밖으로 over-flow 할 때 줄을 바꿀 지 지정합니다.

사실 해당 글에서는 "white-space: pre-wrap;" 키워드가 중요하다.


CSS 키워드 사용으로 문제의 해결

Parents

GoodBox

결과

악성 script 삽입으로 인한 alert도 뜨지 않고 \n도 정상적으로 처리된 것을 볼 수 있다.
CSS의 "white-space: pre-wrap;" 키워드를 사용해서 해결할 수도 있지만
HTML에서의 <pre /> tag를 사용해서도 \n을 잘 처리할 수도 있다.


P.S

마지막으로 draft.js를 사용한 곳에서는 XSS에 관한 이슈가 일어나지 않았다.
dangerouslySetInnerHTML에 대해서 찾아보다가 dangerouslySetInnerHTML 관련 React 공식 문서를 확인하였는데, 생소한 단어들이 오고 가면서 draft.js 라이브러리의 언급이 있었다.
draft.js를 통해 받은 입력을 dangerouslySetInnerHTML을 통해서 보여주고 있었는데, draft.js는 XSS를 막아주는 코드가 내장되어 있나보다.

긴 글 읽어주셔서 감사합니다.

0개의 댓글