HTML을 이스케이프하거나 언이스케이프하는 방법
- 이스케이프나 언이스케이프를 고르세요.
- 이스케이프할 때는 이스케이프에서 대상을 고르세요.
- 페이지나 템플릿에 붙여넣을 HTML이라면 & < > " ‘만.
- UTF-8을 안전하게 처리하지 못하는 페이지, 이메일, 시스템이라면 비 ASCII 문자 전체 포함.
- 파서 테스트처럼 모든 텍스트를 인코딩하려면 모든 문자.
- 형식을 고르세요: 이름 (é), 10진수 (é), 16진수 (é). 이름 형식은 흔히 쓰는 이름이 없는 문자에서는 10진수로 대체됩니다. 텍스트가 요소 내용에만 들어간다면 따옴표 이스케이프를 해제하세요.
- 출력 복사를 누르세요. 바꾸기는 결과를 반대편으로 옮겨 왕복 확인을 할 수 있게 합니다.
언이스케이프는 브라우저의 HTML 파서를 쓰므로 HTML5의 이름 참조 2,000여 개를 모두 지원하고, 10진수와 16진수 참조도 지원합니다. 입력은 절대 HTML로 렌더링되지 않습니다.
자주 쓰는 엔티티
| 문자 | 이름 | 10진수 | 16진수 |
|---|---|---|---|
& | & | & | & |
< | < | < | < |
> | > | > | > |
" | " | " | " |
' | ' (HTML5) | ' | ' |
| 줄 바꿈 없는 공백 | |   |   |
é | é | é | é |
— | — | — | — |
€ | € | € | € |
© | © | © | © |
😀 | 없음 | 😀 | 😀 |
숫자 참조는 유니코드 코드 포인트를 씁니다. 이모지는 UTF-8로 4바이트지만 참조는 하나뿐입니다. 한글도 마찬가지로 가는 가 하나입니다.
이스케이프와 디코딩의 함정
&를 먼저 이스케이프하세요.<를<로 바꾼 다음&를&로 바꾸면&lt;가 됩니다. 직접 만든 이스케이프 함수는 반드시&를 다른 문자보다 먼저 처리해야 합니다.- 텍스트의 인코딩되지 않은
&가 기호로 바뀔 수 있습니다. HTML은 일부 레거시 엔티티를 세미콜론 없이도 인식하므로, 텍스트?id=1©=2¶=3는?id=1©=2¶=3로 표시됩니다. URL 안에서도 모든 앰퍼샌드를&로 쓰세요. - 이중 이스케이프는 페이지에
&lt;b&gt;로 나타납니다. 한 번 언이스케이프한 뒤 어느 계층이 두 번 이스케이프하는지 찾으세요. 는 공백이 아닙니다. U+00A0으로 디코딩되는데, 공백처럼 보이지만 일부 언어에서는 문자열 비교와trim()에서 걸리지 않습니다.- 엔티티는 URL 인코딩이 아닙니다. 링크에서
&는 HTML 소스 안에서 쿼리 파라미터를 구분하고,%26은 값 안의 앰퍼샌드 문자 자체입니다. 후자는 URL 인코더가 처리합니다.
코드에서 이스케이프와 언이스케이프
import html
html.escape('5 > 3 & "quotes"') # '5 > 3 & "quotes"'
html.unescape("Café — ©") # 'Café — ©'
const escapeHtml = s => s.replace(/&/g, "&").replace(/</g, "<")
.replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
const unescapeHtml = s =>
new DOMParser().parseFromString(s, "text/html").documentElement.textContent;
Python의 html.escape는 기본으로 따옴표도 이스케이프하며 '를 '로 씁니다. PHP에서는 보통 htmlspecialchars()를 쓰며, PHP 8.1부터는 기본으로 두 가지 따옴표를 모두 이스케이프합니다. DOMParser는 파싱한 문서의 스크립트를 실행하지 않으므로 브라우저에서 안전하게 디코딩하는 방법입니다. JavaScript 문자열 처리는 JavaScript 페이지에서 더 볼 수 있습니다.
엔티티, Base64, data URI
HTML 엔티티와 Base64는 서로 다른 문제를 풉니다. 엔티티는 HTML 소스 안에서 문자를 안전하게 만들고, Base64는 바이트를 텍스트로 바꿔 파일 전체를 속성 하나에 담을 수 있게 합니다. 완전한 HTML 문서를 data: URI나 JSON 필드에 넣으려면 문자마다 이스케이프하지 말고 HTML을 Base64로로 인코딩하세요.
자주 묻는 질문
HTML에서 꼭 이스케이프해야 하는 문자는 무엇인가요?
텍스트 내용에서는 &와 <, 그리고 관례상 >입니다. 속성 값 안에서는 값을 감싸는 따옴표 "나 '도 이스케이프합니다. 악센트 문자, 한글, 이모지를 비롯한 나머지는 UTF-8 페이지라면 그대로 둬도 됩니다.
'와 '의 차이는 무엇인가요?
둘 다 아포스트로피입니다. '는 HTML5와 XML에 정의되어 있지만 HTML 4에는 없었으므로, 모든 파서와 이메일 클라이언트에서 통하는 형태는 '입니다. 이 도구의 이스케이프는 '를 씁니다.
페이지에 &amp;가 보이는 이유는 무엇인가요?
텍스트가 두 번 이스케이프되었습니다. &가 &가 되고, 두 번째 처리에서 그것이 &amp;가 된 것입니다. 여기서 한 번 언이스케이프하면 의도한 텍스트가 나옵니다. 그리고 불필요한 이스케이프 단계를 없애세요. 대개 이미 이스케이프된 값을 템플릿 엔진이 다시 이스케이프한 경우입니다.
HTML 엔티티 이스케이프로 XSS를 막을 수 있나요?
HTML 텍스트와 따옴표로 감싼 속성 값으로의 주입은 막습니다. 하지만 <script> 블록, javascript: URL, CSS, 따옴표 없는 속성 안의 데이터는 안전해지지 않으며, 이런 문맥에는 각각 맞는 인코딩이 필요합니다. 템플릿 엔진의 자동 이스케이프를 우선 사용하세요.