반응형
Web Development · PHP htmlspecialchars
PHP htmlspecialchars —
특수문자를 엔티티로 이스케이프
<a>를 <a>로 → 화면엔 글자로 보이고 코드로 실행 안 됨
시작 오늘 분석할 코드
<?php $string = '<a href="http://www.namgarambooks.co.kr/">남가람북스</a>'; $result = htmlspecialchars($string, ENT_QUOTES); // 특수문자를 HTML 엔티티로 변환 print $result; ?>
<a href="http://www.namgarambooks.co.kr/">남가람북스</a>
브라우저는 이 결과를 받으면 그대로 글자로 보여준다 — <a>가 링크가 되지 않고 글자 "<a>"로 화면에 나타난다.
용어 용어 정리
htmlspecialchars()HTML 특수문자를 엔티티로 변환
엔티티< 같은 형식의 안전 표기
XSS사용자 입력에 스크립트 끼워 넣기 공격
ENT_QUOTES큰·작은 따옴표 모두 변환
ENT_NOQUOTES따옴표는 변환 X (기본)
vs strip_tagsstrip은 제거, htmlsp는 보존+이스케이프
htmlentities모든 엔티티 변환 (강력하지만 느림)
실무 표준사용자 입력 출력 시 거의 항상 사용
1 변환되는 5가지 문자
| 원본 | 변환 결과 | 설명 |
|---|---|---|
& |
& |
앰퍼샌드 (다른 엔티티의 시작점이라 가장 먼저) |
< |
< |
여는 꺽쇠 (태그 시작 차단) |
> |
> |
닫는 꺽쇠 (태그 끝 차단) |
" |
" |
큰따옴표 (속성 종료 차단) — ENT_QUOTES 또는 ENT_HTML |
' |
' |
작은따옴표 (ENT_QUOTES 필요) |
2 왜 이게 XSS를 막는가?
공격자가 게시판에 <script>alert("hack")</script> 같은 글을 남기면, 그 글을 읽는 모든 사용자의 브라우저에서 alert가 실행된다 (XSS).
// 위험 — 입력을 그대로 출력 print $_POST['comment']; // → "<script>alert("hack")</script>" ← 진짜로 실행됨 // 안전 — 이스케이프 후 출력 print htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8'); // → "<script>alert..." ← 글자로만 보임
3 매개변수 — 어떻게 호출할까
htmlspecialchars($string); // 기본 — 따옴표는 큰 따옴표만 htmlspecialchars($string, ENT_QUOTES); // 큰·작은 따옴표 모두 htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); // 인코딩 명시 (권장) htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8'); // HTML5 규칙
PHP 8.1+에서는 두 번째·세 번째 매개변수를 생략해도 안전한 기본값을 쓴다. 하지만 호환성을 위해
ENT_QUOTES, 'UTF-8'을 명시하는 게 안전.
반응형
4 strip_tags vs htmlspecialchars
| 관점 | strip_tags | htmlspecialchars |
|---|---|---|
| 처리 방식 | 태그 자체를 제거 | 특수문자를 엔티티로 변환 |
| 입력 보존 | 안 됨 (지워짐) | 됨 (그대로 보임) |
| XSS 방어 | 불완전 | 완전 (출력 시) |
| 일부 태그 허용 | 가능 (위험) | 안 됨 (모두 글자로) |
| 주 용도 | 미리보기·검색 인덱스 | 안전한 표시 |
5 실무 — 출력 시 항상 이스케이프
// 모든 사용자 입력 출력에 적용 function e($s) { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); } print "<p>안녕, " . e($name) . "</p>"; print "<input value='" . e($value) . "'>"; // Twig·Blade 같은 템플릿 엔진은 자동 이스케이프 기본 적용
6 자주 하는 실수
| 실수 | 증상 | 해결 |
|---|---|---|
| DB에 이스케이프된 값 저장 | "<" 같은 흔적이 데이터에 | 저장은 원본, 출력 시점에만 이스케이프 |
| 이미 이스케이프한 걸 또 | "&lt;" 등 이중 이스케이프 | 한 번만 적용 |
| nl2br 후 htmlspecialchars | <br>도 이스케이프됨 | htmlsp 먼저, nl2br 나중 |
| 속성 안에 ENT_NOQUOTES | '로 속성 종료 가능 → XSS 위험 | ENT_QUOTES 사용 |
| 한글 깨짐 | 인코딩 미지정 시 일부 PHP 버전 | 'UTF-8' 명시 |
핵심 한 줄 요약
htmlspecialchars()& < > " ' 를 HTML 엔티티로 변환
XSS 방어사용자 입력 출력 시 거의 항상 적용
ENT_QUOTES큰·작은 따옴표 모두 처리 (권장)
UTF-8 명시한글 안전 처리
vs strip_tagsstrip은 제거, htmlsp는 보존+이스케이프
저장 X 출력 ODB에는 원본, 화면 출력 시만 변환
템플릿Twig/Blade 등은 기본 자동 이스케이프
반응형
'php' 카테고리의 다른 글
| PHP date — 타임스탬프를 사람이 읽는 형식으로 완전 정리 (0) | 2026.06.15 |
|---|---|
| PHP mb_strlen vs strlen — 한글 글자수와 바이트수 차이 완전 정리 (0) | 2026.06.15 |
| PHP strip_tags — HTML 태그 제거 완전 정리 (0) | 2026.06.15 |
| PHP str_replace — 문자열 찾아 바꾸기 완전 정리 (0) | 2026.06.15 |
| PHP trim — 문자열 양끝 공백 제거 완전 정리 (0) | 2026.06.15 |
왕진 블로그

댓글