HTML 엔티티 인코더 / 디코더

특수 문자를 HTML 엔티티(&, <, ©)로 변환하거나 엔티티를 읽기 쉬운 텍스트로 다시 디코딩합니다 — 양방향, 실시간.

조회수 960회

작동 방식

HTML은 자체 문법을 위해 몇 가지 문자를 예약해 둡니다. <>는 태그를 표시하고, &는 엔티티 참조를 시작합니다. 페이지에 삽입되는 콘텐츠 — 댓글, 사용자 이름, 다시 표시되는 검색어 등 — 안에 이 문자들이 그대로 나타나면 브라우저는 이를 텍스트로 표시하는 대신 마크업으로 해석하려 합니다. 인코딩은 이런 문자를 엔티티 형태(&lt;, &gt;, &amp;)로 변환하여 해석되지 않고 글자 그대로 렌더링되게 합니다. 디코딩은 그 반대로, &amp;&#8217; 같은 엔티티를 실제로 나타내는 문자로 되돌립니다.

이는 단순한 표시상의 문제가 아니라 보안 통제입니다. 댓글 입력창이 사용자 입력을 받아 인코딩하지 않고 페이지 HTML에 그대로 삽입하면, 방문자가 <script>...</script>를 입력해 그 스크립트가 다른 모든 방문자의 브라우저에서 실제로 실행되게 만들 수 있습니다. 이런 취약점 유형을 크로스 사이트 스크립팅(XSS)이라고 하며, 신뢰할 수 없는 출력을 HTML에 넣기 전에 인코딩하는 것이 이에 대한 표준 방어책입니다. 예를 들어 5 < 10 & 10 > 5라는 텍스트를 인코딩하면 5 &lt; 10 &amp; 10 &gt; 5가 되며, 이는 올바르게 표시되고 마크업으로 오인될 수 없습니다.

알아두어야 할 사항

  • 이름 붙은 엔티티와 숫자 엔티티는 같은 문자를 다르게 표현합니다. &apos;(이름형)와 &#39;(숫자형)는 둘 다 작은따옴표를 의미하지만, 이름형 엔티티는 파서가 그 특정 이름을 인식해야만 동작합니다. 반면 숫자형 엔티티(10진수 또는 &#x 16진수)는 어디서나 지원되므로 기계 생성 출력에 더 안전합니다.
  • 인코딩만으로는 충분하지 않습니다. 인코딩은 텍스트 콘텐츠를 보호할 뿐이며, 속성값·URL·인라인 자바스크립트 컨텍스트는 각각 별도의 이스케이프 규칙이 필요합니다. href="javascript:..." 안의 값이나 <script> 블록 안의 값은 일반 본문 텍스트와는 다른 규칙으로 파싱되기 때문입니다.
  • 변환은 로컬에서 이루어집니다. 이 도구는 브라우저 자체의 DOM 파서를 사용하므로 아무것도 업로드되거나 기록되지 않습니다.
  • 모든 서버 사이드 템플릿 언어가 기본적으로 자동 이스케이프를 하지는 않습니다. 오래된 PHP 출력 방식이나 단순 문자열 연결처럼 이스케이프 함수를 명시적으로 호출해야 하는 경우가 있으며, 이를 잊는 것이 실제 XSS 버그의 가장 흔한 원인 중 하나입니다.
  • 일부 엔티티는 시각적으로 거의 구별되지 않습니다. 곧은 아포스트로피(')와 타이포그래피용 오른쪽 작은따옴표(&#8217;)는 화면에서는 거의 같아 보이지만 서로 다른 바이트 시퀀스이며, 코드 샘플이나 URL에서는 이 차이가 중요합니다.

구체적인 전후 비교: Nice post! 5 < 10, right?라는 댓글 내용은 일반 텍스트로서는 특별한 처리가 필요 없지만, 이스케이프 없이 HTML 템플릿에 삽입되는 순간 악의적인 방문자가 대신 <img src=x onerror=alert(1)>를 제출할 수 있습니다. 인코딩은 이를 실행되는 이미지 오류 핸들러가 아니라 무해하고 눈에 보이는 텍스트로 바꿔 줍니다.

자주 묻는 질문

HTML에 넣기 전에 텍스트를 왜 인코딩해야 하나요?

이스케이프되지 않은 <나 &가 HTML 콘텐츠 안에 있으면 마크업으로 해석되어 페이지 레이아웃이 깨지거나, 더 심각하게는 삽입된 <script>나 <img onerror> 태그가 실제로 실행될 수 있습니다(크로스 사이트 스크립팅). &lt;와 &amp;로 인코딩하면 사용자가 무엇을 입력했든 텍스트가 그대로 무해하게 유지됩니다.

이름 붙은 엔티티와 숫자 엔티티를 모두 처리하나요?

네 — 디코딩은 이름 붙은 엔티티(&amp;copy;)와 숫자 엔티티, 즉 10진수(&amp;#169;)와 16진수(&amp;#x00A9;) 표기 모두를 이해합니다. 세 가지 모두 동일한 © 문자를 나타내며, 이 도구는 어떤 표기든 실제 글리프로 정규화합니다.

이름 붙은 엔티티 대신 숫자 엔티티를 쓰는 이유는, 혹은 그 반대는 무엇인가요?

이름 붙은 엔티티(&amp;apos;, &amp;hellip;)는 소스 코드에서 더 읽기 쉽지만, 파서가 정확한 이름을 인식해야 동작하며 흔치 않은 일부 이름은 오래된 도구에서 지원이 일관되지 않을 수 있습니다. 숫자 엔티티(&amp;#39;, &amp;#8230;)는 버전이나 제조사와 무관하게 모든 HTML 파서에서 보편적으로 이해되므로, 자동화 도구나 정제(sanitization) 라이브러리는 대개 숫자 엔티티를 선호합니다.

인코딩만으로 페이지가 XSS로부터 안전해지나요?

인코딩은 텍스트 노드를 처리할 뿐이며, HTML에는 그 외에도 속성값 안, URL 안, <script>나 <style> 블록 안 등 다른 삽입 지점이 있습니다. 브라우저 파서는 문서 내 위치에 따라 규칙을 다르게 적용하므로 각 지점마다 고유한 이스케이프 방식이 필요합니다. 텍스트 콘텐츠를 엔티티로 인코딩하는 것은 필수적인 한 단계일 뿐 전체 방어책은 아닙니다. 제한된 HTML을 의도적으로 허용하고 싶을 때는 태그 전체를 제거하거나 다시 쓰는, 더 폭넓은 "정제(sanitizing)" 단계를 담당하는 별도의 전용 도구가 필요합니다.

제 텍스트가 어딘가로 전송되나요?

아니요 — 변환은 브라우저의 자체 DOM 파서를 사용해 즉시 이루어집니다. 아무것도 업로드되거나 기록되거나 저장되지 않으므로, 인젝션 시도가 의심되는 내용을 포함해 실제 사용자 제출 콘텐츠를 테스트하기에도 안전합니다.

댓글

아직 댓글이 없습니다 — 첫 댓글을 남겨보세요!

비슷한 도구