이게 뭔가요?
HTML에서 특별한 의미를 갖는 문자를 엔티티로 바꾸거나, 엔티티를 원래 문자로 되돌립니다.
왜 필요한가
이런 문자열을 HTML에 그대로 넣으면 화면이 깨집니다.
<a href="/search?q=1&page=2">검색 & 이동</a>
브라우저가 <a>를 태그로 읽어버리기 때문이죠. 글자 그대로 보여주려면 이렇게 바꿔야 합니다.
<a href="/search?q=1&page=2">검색 & 이동</a>
꼭 바꿔야 하는 다섯 글자
| 문자 | 이름 참조 | 숫자 참조 | 쓰는 곳 |
|---|---|---|---|
& |
& |
& |
모든 엔티티의 시작 문자 |
< |
< |
< |
태그 시작 |
> |
> |
> |
태그 끝 |
" |
" |
" |
속성값 큰따옴표 |
' |
' |
' |
속성값 작은따옴표 |
순서가 중요합니다
&를 가장 먼저 바꿔야 합니다.
<를 먼저 <로 바꾸고 나서 &를 처리하면, 방금 만든 <의 &까지 또 바뀌어 &lt;가 됩니다. 화면에는 <라는 글자가 그대로 보이죠.
모든 엔티티가 &로 시작하기 때문에 생기는 문제이고, 직접 치환 코드를 짤 때 가장 흔히 밟는 함정입니다. 이 도구는 그 순서를 지킵니다.
최소 변환과 전체 변환
최소 — HTML에서 의미를 갖는 다섯 글자만 바꿉니다. 문서가 UTF-8이라면 한글이나 이모지는 그대로 둬도 됩니다. 대부분의 경우 이걸 쓰세요.
전체 — 아스키(127) 밖의 모든 문자를 숫자 참조로 바꿉니다. 문자 인코딩을 신뢰할 수 없는 곳에 씁니다.
- 오래된 이메일 클라이언트
- 인코딩 설정을 바꿀 수 없는 레거시 시스템
- 아스키만 허용하는 전송 경로
대신 용량이 크게 늘어납니다. 한글 한 글자가 한처럼 여덟 바이트가 되니까요.
안전하게 만들었습니다
인코딩할 때 문자열을 DOM에 넣었다가 빼내는 흔한 방법을 쓰지 않습니다. 그 방식은 입력이 실제로 파싱되기 때문에, 인코딩을 하려다 오히려 스크립트를 실행시킬 수 있습니다.
디코딩에는 브라우저 파서가 필요하지만(엔티티 이름이 2천 개가 넘습니다), textarea에 넣고 value로만 읽어 스크립트가 실행되지 않게 했습니다.
주의할 점
- 변환은 브라우저 안에서만 이뤄집니다.
- 이 도구가 XSS를 막아주지는 않습니다. 사용자 입력을 화면에 넣을 때는 서버·프레임워크 쪽에서 이스케이프하세요. 이건 개발 중에 문자열을 확인하는 용도입니다.
- URL에 넣을 문자열이라면 URL 인코더를 쓰세요. 규칙이 다릅니다.