HTML Purifier - XSS 방어

inhalin·2021년 4월 18일
0

일터지식

목록 보기
3/14
post-thumbnail

HTML Purifier

http://htmlpurifier.org/
https://blog.devflow.kr/212

  • whitelist에 있는 안전하고 허용된 태그들만 남기고 그 외 악성 코드(XSS)를 제거한다. W3C 스펙에 맞는 표준 준수 여부도 확인해준다.

blacklist를 사용하면 목록에 없는 악성코드는 막을 수 없기 때문에 안전한 코드만 허용할 수 있게 whitelist 사용

  • 허용하길 원하는 엔티티를 whitelist 목록에 추가할 수 있다.
  • config\purifier.php
  • 같이 사용하면 좋은 extension
    • iconv : utf-8 인코딩 변환
    • bcmath : 단위 변환, 이미지 충돌 보호
    • tidy : html 보기 좋게
  • 같이 사용하면 좋은 라이브러리
    • CSSTidy : css 보기 좋게

html purifier 사용하기

  1. 라이브러리 포함하기
require_once '/path/to/library/HTMLPurifier.auto.php';

library/ 폴더만 필수이고 다른건 프로덕션 환경에서는 제거해도 됨.

만약 PEAR로 HTML Purifier를 설치했다면 아래 코드만 추가해주면 된다.

require_once 'HTMLPurifier.auto.php';
  1. 환경설정하기

HTML Purifier Configuration Documentation

  • HTML.Allowed : 허용할 html 요소와 속성 지정. HTML.AllowedElements나 HTML.AllowedAttributes를 지정해주면 덮어써짐(HTML.Allowed 효과 x).
  • HTML.TargetBlank : true일때 외부링크는 전부 target=blank
  • AutoFormat.RemoveEmpty : 내용이 없거나 공백만 있는 태그 삭제
  • AutoFormat.RemoveEmpty.RemoveNbsp : 공백이나 nbsp만 있는 태그 삭제
  • HTML.SafeIframe : iframe 허용여부 지정. 반드시 URI.SafeIframeRegexp에 허용할 iframe을 지정해줘야 함.
  1. 주의사항
  • 다른 XSS 공격을 막아주는 라이브러리들에 비해 무겁다(= 느리다) -> 페이지 표시할 때마다 매번 필터링하지 말고, DB에 저장하기 전에 한 번만 필터링하기
  • 문법에 어긋나는 태그는 제거하기 때문에 HTML 소스가 심하게 망가진 경우 주의
  • 첨부파일 업로드 사용한 XSS 공격은 별도로 막아줘야함
  • https://devlink.tistory.com/133

e()

  • Laravel에서 제공하는 helpers에 있는 메서드
  • php의 htmlspecialchars() 함수를 실행(모든 html 엔티티를 변환)
  • UTF-8 인코딩
$str = "<strong>줄바꿈</strong>이 안되는것을<script>alert('attack!');</script>\r\n되게 하라";

echo e($str);
dd(e($str));

clean()

  • HTML Purifier 함수
  • whitelist에 있는 태그들은 놔두고 나머지는 전부 삭제
$str = "<strong>줄바꿈</strong>이 안되는것을<script>alert('attack!');</script>\r\n되게 <mytag>하라</mytag>";

echo clean($str);
dd(clean($str));

// <strong>태그는 남기고
// whitelist에 없는 <script>태그와 <mytag>는 삭제

view_text()

  • 임의로 만든 helpers에 있는 메서드
  • e()로 html 엔티티 전부 변환 -> nl2br()로 줄바꿈 -> html purifier로 clean() 해준 결과값 반환(문자열을 p 태그로 감싸줌)
$str = "<strong>줄바꿈</strong>이 안되는것을<script>alert('attack!');</script>\r\n되게 하라";

echo view_text($str);
dd(view_text($str));

0개의 댓글