☕️ JAVASCRIPT

HTML Entities 치환 라이브러리, html-entities

1HOON 2022. 7. 19. 01:58

크로스 사이트 스크립팅(Cross Site Scripting, XSS)을 방지하기 위해 대부분 요청/응답 본문의 HTML Entities를 escape합니다.

이 때, 사용자에게 노출되는 데이터는 unescape된 데이터이어야 사용자가 입력한 그대로 보여질 것입니다.

 

어떤 방식이 주로 사용되는지는 모르지만, 제 경험상으로는 백엔드에서 HTML Entities를 escape 하고 프론트엔드에서 unescape 했기 때문에 위 방식으로 예를 들도록 하겠습니다.

 

 

HTML Entities란?


HTML에 미리 예약된 몇몇 문자를 의미하며, HTML에서 해당 문자를 사용하면 웹 브라우저는 그 문자를 다른 문자와는 다른 의미로 해석합니다. 대표적인 예로는 각각 <>를 의미하는 &lt;, &gt;가 있습니다.

 

만약 아래와 같은 텍스트를 표현하고 싶다면 어떻게 HTML 코드를 작성해야 할까요?

<p> 태그지롱~!

아래처럼 HTML Entities를 사용하면 됩니다.

&lt;p&gt; 태그지롱~!

전체 HTML Entities 목록은 여기서 확인할 수 있습니다.

 

 

이걸 왜 설명하냐구요?


다시 한 번 설명드리자면, XSS 공격을 방지하기 위해 백엔드에서는 요청 본문을 escape합니다.

때문에 클라이언트에서 서버에 아래 본문으로 요청을 보내면, 서버에서는 요청 본문을 escape한 뒤 로직을 처리하는 것이죠.

서버의 HTML Entities escape 처리

그럼 반대로, 저장된 데이터를 클라이언트로 넘겨줄 때는?

서버는 HTML Entities unescape를 하지 않는다

데이터를 그대로 내려줍니다. 클라이언트에서 이 데이터를 단순히 value로 사용할 지, innerHTML로 사용할지 모르기 때문입니다.

이 데이터를 단순 value로 사용한다면 아래와 같이 텍스트 에리어에 데이터가 사용자가 입력한 것과는 다르게 보이게 됩니다.

그래서 프론트엔드에서는 이 경우에 데이터를 unescape해 사용합니다.

이 때 HTML Entities 별로 unescape를 구현하기엔 너무 힘들기 때문에 라이브러리를 사용하려고 합니다.

 

 

lodash


Javascript 최고 인기 라이브러리 중 하나인 lodash에서도 unescape 기능을 제공해주고 있었습니다.

📝 API Doc

var _ = require('lodash');
_.unescape('&lt;p&gt; 태그지롱~!')

예시 코드는 정상적으로 unescape 되었지만 큰 문제가 있었습니다.

lodash의 unescape 함수는 &amp;&lt;&gt;&quot;, &#39; 이 다섯개의 HTML entities만을 처리해주고 있었습니다.🤦🏻

 

 

html-entities


결국엔 html-entities 라는 라이브러리를 찾게 되었습니다.

다행히도 이 라이브러리는 HTML5의 모든 entities를 치환해준다고 하네요. 사용 방법도 어렵지 않습니다.

import {decode} from 'html-entities';

decode('&lt;p&gt; 태그지롱~!');

2022.07.19 기준 Github Stars도 472개받았고 8710461개의 Repository에서 사용중이라고 하니 믿고 쓰셔도 좋을지도...?ㅎ

반응형