본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

PHP htmlspecialchars — HTML 특수문자 이스케이프 + XSS 방어 완전 정리

by 왕진 2026. 6. 15.
반응형

 

 

Web Development · PHP htmlspecialchars

PHP htmlspecialchars —
특수문자를 엔티티로 이스케이프

<a>를 &lt;a&gt;로 → 화면엔 글자로 보이고 코드로 실행 안 됨
시작 오늘 분석할 코드
<?php $string = '<a href="http://www.namgarambooks.co.kr/">남가람북스</a>'; $result = htmlspecialchars($string, ENT_QUOTES); // 특수문자를 HTML 엔티티로 변환 print $result; ?>
&lt;a href=&quot;http://www.namgarambooks.co.kr/&quot;&gt;남가람북스&lt;/a&gt;

브라우저는 이 결과를 받으면 그대로 글자로 보여준다 — <a>가 링크가 되지 않고 글자 "<a>"로 화면에 나타난다.

용어 용어 정리
htmlspecialchars()HTML 특수문자를 엔티티로 변환
엔티티&lt; 같은 형식의 안전 표기
XSS사용자 입력에 스크립트 끼워 넣기 공격
ENT_QUOTES큰·작은 따옴표 모두 변환
ENT_NOQUOTES따옴표는 변환 X (기본)
vs strip_tagsstrip은 제거, htmlsp는 보존+이스케이프
htmlentities모든 엔티티 변환 (강력하지만 느림)
실무 표준사용자 입력 출력 시 거의 항상 사용

1 변환되는 5가지 문자
원본 변환 결과 설명
& &amp; 앰퍼샌드 (다른 엔티티의 시작점이라 가장 먼저)
< &lt; 여는 꺽쇠 (태그 시작 차단)
> &gt; 닫는 꺽쇠 (태그 끝 차단)
" &quot; 큰따옴표 (속성 종료 차단) — ENT_QUOTES 또는 ENT_HTML
' &#039; 작은따옴표 (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'); // → "&lt;script&gt;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;" 같은 흔적이 데이터에 저장은 원본, 출력 시점에만 이스케이프
이미 이스케이프한 걸 또 "&amp;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 등은 기본 자동 이스케이프
반응형

댓글