Technote

보안 실무

연재 자식 테마 개발 실무 8부 중 5부

출력 이스케이프 — 어느 자리에 무엇을 쓰나

이스케이프는 저장할 때가 아니라 출력할 때 합니다. 같은 값이 본문 · 속성 · 주소로 나갈 수 있고, 자리마다 안전의 정의가 다르기 때문입니다.

템플릿에서 값을 출력할 때 지켜야 하는 규칙은 하나입니다. 출력하는 그 자리에서, 그 자리에 맞는 함수로 감싼다. 워드프레스 코딩 표준에서 이스케이프 없는 echo 가 리뷰에서 반려되는 이유가 이것입니다.

왜 입력이 아니라 출력인가

“저장할 때 한 번 처리해 두면 되지 않나” 는 자연스러운 질문입니다. 답은 같은 값이 여러 자리로 나가기 때문입니다. 글 제목 하나만 해도 본문 텍스트로, title 속성 값으로, 검색 결과의 JSON 으로 나갑니다. 세 자리의 안전 규칙이 각각 다릅니다.

입력 시점에 이스케이프하면 그 순간 자리 하나를 골라 고정하는 셈이고, 나머지 자리는 전부 어긋납니다. 게다가 원본이 훼손되어 검색 · 정렬 · 내보내기가 함께 이상해집니다. 반대로 출력 시점에 처리하면 원본은 원본대로 남고, 자리마다 맞는 처리를 할 수 있습니다.

실무적인 이점도 큽니다. 이스케이프가 echo 와 같은 줄에 있으면 한 줄만 보고 안전 여부를 판정할 수 있습니다. 저장 로직까지 거슬러 올라가 확인해야 한다면 그것은 검토가 아니라 추적입니다.

자리별 함수

출력 자리와 그 자리에 맞는 함수 — 자리가 바뀌면 함수도 바뀐다
<a class="<?php echo esc_attr( $class ); ?>"
   href="<?php echo esc_url( $url ); ?>">
    <?php echo esc_html( $title ); ?>
</a>

<div class="entry">
    <?php echo wp_kses_post( $rich_html ); ?>
</div>

esc_html() 과 esc_attr() 을 굳이 나누는 이유는 속성 안에서는 따옴표가 탈출 문자이기 때문입니다. 값에 따옴표가 섞이면 속성이 그 자리에서 끊기고 그 뒤가 새로운 속성으로 해석됩니다. 태그 밖에서는 문제가 되지 않는 문자가 태그 안에서는 문제가 되는 것입니다.

esc_url() 은 이스케이프에 더해 허용된 프로토콜인지도 봅니다. 사용자가 넣은 주소가 스크립트를 실행하는 형태일 수 있고, 그것을 esc_attr() 로는 걸러내지 못합니다. 링크 자리에는 반드시 esc_url() 을 씁니다.

wp_kses_post() 는 성격이 다릅니다. 이스케이프가 아니라 허용 목록에 따른 필터링이라, 문단 · 링크 · 강조 같은 태그는 살아남고 스크립트는 제거됩니다. 에디터로 작성된 본문처럼 마크업을 살려야 하는 값에만 씁니다.

흔한 오용 세 가지

자리를 잘못 고르면 안전해 보이는 코드가 안전하지 않다

첫 줄은 눈에 보여서 금방 발견됩니다. 문제는 두 번째와 세 번째입니다 — 화면이 멀쩡해 보이므로 리뷰를 통과합니다. “이스케이프 함수를 썼다” 는 사실만으로 안전이 보장되지는 않는다는 뜻입니다.

번역이 섞이면 esc_html__() · esc_attr_e() 처럼 합쳐진 함수를 씁니다. 번역문에도 같은 규칙이 적용되기 때문입니다 — 번역 파일은 우리가 통제하지 않는 경우가 있습니다.

마지막으로 esc_url() 과 esc_url_raw() 를 구분합니다. 화면에 출력할 때는 앞쪽을, DB 저장이나 리다이렉트처럼 기계가 소비할 때는 뒤쪽을 씁니다. 앞쪽은 HTML 용으로 & 를 엔티티로 바꾸기 때문에 그대로 저장하면 값이 달라집니다.

테마 · 플러그인 코드의 보안 관행은 보안 아카이브에서 더 다루고, 운영 중인 사이트의 취약점 진단은 최적화 지원 사업에 전/후 대조로 포함돼 있습니다.

다음 회차

출력이 안전해졌으니 이제 무엇을 출력할지 정할 차례입니다. 다음 회차는 템플릿 안에서 보조 쿼리를 쓰는 방법이고, 한 줄을 빠뜨렸을 때 생기는 아주 헷갈리는 증상을 함께 다룹니다.

이 주제의 다른 글

노하우 목록으로

보안 실무

리드 데이터는 자산이면서 책임입니다

연락처 목록은 마케팅 자산이지만 동시에 개인정보입니다. 필요한 만큼만 받고, 기간을 정해 두고, 그 기간이 지나면 실제로 지우는 세 가지가 핵심입니다.

마케터 3분 읽기

보안 실무

분석과 개인정보 — 최소 수집과 고지의 실제

배너를 띄우는 것과 동의를 받는 것은 다릅니다. 무엇을 왜 수집하는지 스스로 설명할 수 있어야 하고, 보관 기간은 방치가 아니라 결정이어야 합니다.

마케터 4분 읽기

₩270,000 · 신청하기