TIP게시판

제목 XSS filtering에 대해서
글쓴이 호짱 작성시각 2019/08/13 00:15:59
댓글 : 5 추천 : 0 스크랩 : 0 조회수 : 12117   RSS

XSS Cross-site Scripting

(어제 적은 내용이 너무 우왕좌왕하고 대안에대한 이야기는 없어서 대량 수정했습니다.)

Codeigniter3 XSS filtering issue

회사에서 이 전에 진행한 프로젝트에서 Codeigniter 3 Framework를 사용하였는데, 이 사이트의 HTML을 사용하는 영역을 제외하고는 Input Class에서 XSS filtering을 한 후 Parameter 값을 사용했습니다.

그런데 이 사이트 사용자 중 한 분에게 입력한 내용이 일부 사라졌다는 오류 제보를 받았습니다.

확인해보니 Codeigniter 3(이하 CI3)에서 XSS filtering을 할 때 특정 문자열 패턴이 HTML로 인식되서 사라지는 현상이었고, 원인은 '% 33', '% 40' 와같이 엔퍼센트 특수 문자 뒤에 한칸 띄우고 숫자가 2개 이상 오는 패턴일 때 XSS방어 기능이 이 패턴을 HTML entity로 인식하고 제거해버리는 것이었습니다.

CI3 가이드 문서를 보면 CI의 XSS filtering 기능은 매우 강력하게 작용하으므로 전역적으로 사용하지 말라고 나와있습니다.

하지만 제 생각에는 이런 오류라면 부분적으로 사용한다고 하더라도 안심하고 CI XSS filtering 기능을 적용하기에는 문제가 있다고 생각이 들었습니다.

사용자가 입력하는 불특정한 데이터를 XSS filtering 기능에 맞기기에는 데이터 자체가 훼손될 수 있기 때문이죠.

실제로 그 이유로 불편함을 제보 받았구요.

짧은 영어로 stackoverflow에 질문을 해보니

https://stackoverflow.com/questions/56572511/some-text-was-removed-while-xss-filtering-in-codeigniter 

고맙게도 댓글로 도움을 주신분이 XSS filtering 쓰지 말라고하면서 XSS filtering 기능의 문제에 대해서 설명한 링크를 알려주더라구요.

https://stackoverflow.com/questions/5337143/codeigniter-why-use-xss-clean

그러면 XSS 방어는 포기?

그러면 XSS 방어는 어떻게 해야할까? 에 대해서 생각을 해야하는데요.

위에 두 번째 링크의 질문에 대한 답변 글 중 Useful 점수가 가장 높은 글 내용의 결론은

'XSS는 출력(output)의 문제이지 입력(input)의 문제가 아니다' 라는 것입니다.

그러니 input parameter에서 filtering 하기보다는 Output할 때 escape해주는 것이 좋은 방법입니다.

글을 적으면서 확인해보니 CI3 가이드 문서에도 XSS 이스케이프는 output에서 진행하라는 안내가 있었습니다.

http://www.ciboard.co.kr/user_guide/kr/libraries/input.html

개인적으로도 이 생각에 동의합니다. 하지만 웹 애플리케이션(Web application)에 출력되는 모든 데이터를 escape하는 일은 상당히 번거로운 일입니다.

<?php $variable = "<p>씨아이 코리아</p>"; ?>
<?=htmlentities($variable)?>
<?=htmlspecialcharacters($variable)?>
// 출력
// <p>씨아이 코리아</p>

PHP 내장 함수로 escape처리를 하려면 아마 모든 문자열을 이런식으로 출력해줘야하니까요.

그런데 Twig 같은 View 페이지 Template engine을 사용하면 escape를 좀 더 간단하게 처리할 수 있습니다.

{{ var }}
{{ var|escape }}
{{ var|e }}         {# shortcut to escape a variable #}

PHP 스크립트 시작 태그인 <?php 태그를 사용하지 않아도되서 View 페이지 코드를 작성할 때 HTML과 함께 사용하기도 더 편리하고 위 코드처럼 escape처리 뿐만아니라 일반적인 문자열 출력도 훨씬 간편해집니다.

이 링크는 CI3에서 Twig를 상용할 수있게 해놓은 Library Github 저장소입니다.

https://github.com/kenjis/codeigniter-ss-twig

PHP에서 View Template engine은 Twig만 있는건 아닙니다.

Laravel Framework에 내장된 Blade Template engine도 있는데요.

Blade도 CI3에서 사용할 수있습니다.

https://khanorder.tistory.com/entry/ci-blade

제가 작성한 CI3에서 Blade Template engine 사용법에 대한 글입니다.

Blade에서도 Twig처럼 간결하고 쉽게 문자열을 escape하고 출력할 수있습니다.

// blade는 기본 출력이 escape
{{ $variable }}
 
// escape 없이 출력할려면 이렇게
{!! $variable !!}

이렇게 말이죠~

이상 CI3 XSS filtering 기능의 문제점과 좀 더 안전하고 편안한 XSS 방어 방법으로 View Template engine을 통한 문자열 escape 방법에 대해 적어봤습니다.

태그 Input Class,xss filtering issue,sanitizing html
관련링크 https://stackoverflow.com/questions/56572511/some-text-was-removed-while-xss-filtering-in-codeigniter
https://stackoverflow.com/questions/5337143/codeigniter-why-use-xss-clean
https://khanorder.tistory.com/entry/Codeigniter3-XSS-filtering-issue
 다음글 A PHP Error was encountered (1)
 이전글 CI3 에서 Doctrine ORM(Object-rel... (6)

댓글

kaido / 2019/08/13 09:57:00 / 추천 0

참고 글에도 나와있지만,  대책안으로 저는 http://htmlpurifier.org/  를 사용합니다.

CI 라이브러리형태로 만들어진 것도 있어 사용도 편리합니다.

https://github.com/refringe/codeigniter-htmlpurifier

 

정확하게 CI 의 xss 필터는 매우 강력합니다.

마치 한국의 공무원마냥 제한이 나오면 싸잡아서 전부 막는 형태입니다.

이는 특히 위지윅 게시판 붙일때 크게 문제가 됩니다.

해서 팁 게시판에도 글로벌 xss 기능을 꺼두고 부분적으로 xss 기능을 사용하시도록 추천하고 있습니다.

호짱 / 2019/08/13 18:48:03 / 추천 0

네 저도 부분적으로 사용하긴 했지만 사용자가 입력하는 데이터를 받아오는 파라미터에

어떤 내용이 입력될지 예측할수 없는 상황에서 데이터가 불안전하게 필터링된다면

부분적으로도 사용하기도 힘들것 같아서 이 글을 공유했습니다.^^;

 

말씀하신 htmlpurifier도 강력한 플러그인이긴 한데 정확한 수치를 말씀드리지는 못해서 아쉽지만 개인적 경험으론 다수의 파라미터에 적용했을 때 퍼포먼스가 썩 좋지는 않았던 것 같습니다.

그래서 게시판 글작성과 같은 html데이터를 입력받는 페이지에서만 특정 html 요소 데이터를 금지하거나(black list) 특정 html 데이터만 허용할 때(white list) 사용했던 기억이 납니다.

 

그리고 같이 첨부한 링크에 가장 많은 점수를 받은 답변을 보면 결론은 'XSS는 출력의 문제지 입력의 문제가 아니다.'라고 하는 내용이 있는데요.

개인적인 생각으론 XSS방어에 있어서는 이게 가장 정답인것 같습니다.

그러고 보니 CI3 가이드 문서에도 XSS 이스케이프는 output애서 진행하라고 나오네요.

http://www.ciboard.co.kr/user_guide/kr/libraries/input.html

페이지에 데이터를 출력할 때 html이 포함되지 않은 데이터라면 전부 escape하는 거죠.

그런데 이렇게 하려면 보통 php 출력할 때 사용하는

<?=$variable?>

이 부분을

<?=htmlspecialchars($variable)?>
// 혹은
<?=htmlentities($variable)?>

이렇게 해줘야 합니다. 굉장이 번거로운 일이지요.

그래서 Twig(https://twig.symfony.com/) 같은 view template engine을 사용하시면 출력으로 XSS 방어가 손쉽게 처리됩니다.

{{ var }}
{{ var|escape }}
{{ var|e }}         {# shortcut to escape a variable #}

이런 방식으로요.

CI3에서 Twig를 사용할 수 있는 Library입니다. https://github.com/kenjis/codeigniter-ss-twig

Twig만 있는건 아닙니다 Laravel에서 사용하는 Blade template engine도 비슷한 형식입니다.

// blade는 기본 출력이 escape
{{ $variable }}

// escape 없이 출력할려면 이렇게
{!! $variable !!}

사용법은 Blade가 조금 더 간편한 것 같습니다.

CI3에 Blade를 적용하는 방법은 이 전에 포스팅한 적이 있어서 링크 같이 남깁니다.

https://khanorder.tistory.com/entry/ci-blade

cikorea 이 게시판에도 같은 포스팅을 남겼네요^^;

https://cikorea.net/bbs/view/tip?idx=18704&page=2&view_category=&lists_style=

kaido / 2019/08/16 15:33:47 / 추천 0

xss 필터를 템플릿엔진에서 처리한다는것은 하나의 방법이라고 생각 됩니다.

다만 xss 필터만을 위해서 템플릿엔진 도입은 약간 별도의 문제이라고 생각 합니다.

템플릿엔진 자체가 워낙 호불호가 크기때문입니다.

도입되지 않은 회사에 도입 하자고 하는것도 쉽지 않고, 도입한 회사에서 빼자고 하기도 쉽지 않습니다.

어떻게 하는건 좋은데 그 뒤의 대책안이 따라와야만 합니다.

 

더불어서 잘 사용되지 않아서 그렇지 CI 에도 템플릿파서는 존재합니다 ( ..)

http://www.ciboard.co.kr/user_guide/kr/libraries/parser.html

호짱 / 2019/08/16 23:49:07 / 추천 0

우선 재미없는 내용에다가, 잘 못쓴 글인데 읽고, 댓글로 의견 말씀해주셔서 감사드립니다 kaido님.

네 맞습니다. XSS와 템플렛 엔진은 별도의 문제이고, 호불호가 갈리는 것은 맞는 말입니다.

템플릿 엔진을 사용중이지 않은 프로젝트에 적용을 하는것도 꽤 큰 작업이 필요한 일이구요.

 

하지만 진행중인 프로젝트가 XSS 방어에 대한 기준이 엄격하다면 고려해봐야 할 사항이라고 생각합니다.

재차 말씀드리지만 좀 더 확실한 XSS 방어와  데이터가 훼손될 염려도 줄일 수 있는 방법은 템플릿 엔진이라고 생각합니다.

본 글에 말씀 드렸듯이 입력(Input) 영역에서 데이터의 XSS를 제거하는 기능이 불완전하기 때문이죠.

CI의 Input 기능을 사용중 경험한 애로사항을 공유하려 쓴 글인데 혹 Framework 자체를 낮춰말하는 읽힐까봐 걱정이됩니다.

입력 영역에서의 XSS 방어가 불안전 한 것은 다른 프레임워크 다른 언어를 사용한다고 해도 마찬가지 일것입니다.

%나 &와 같은 특수문자를 사용하게되면 일반적인 문자열 속에서 HTML entity 문자열을 100% 구분하기 힘드니까요.

 

제가 템플릿 엔진을 소개한 이유는 XSS방어를 위한 안전하고 생산성 좋은 escape 방법 때문입니다.

그런데 CI 템플릿 파서에는 Twig 같은 quick escape 패턴이나 Blade 처럼 기본 출력 패턴이 escape되는 기능은 없는 것 같습니다.

제가 작업한 프로젝트에 CI 템플릿 파서를 사용해본적은 없어서 잘못 알고 있을수도 있지만, CI3 가이드 문서에 나온 내용만 봤을 때는 escape에 관한 내용은 없어보입니다.

그리고 단순 템플린 엔진으로의 기능으로만 봤을 때도 CI템플릿 파서보다 Twig나 Blade가 좋은 점이 더 많은 것 같습니다.

CI의 템플릿 파서와 Twig나 Blade의 기능을 항목, 항목 직접 비교하기에는 XSS에 관한 내용과 벗어나기 때문에 escape에 관해서만 비교해봤습니다.

 

템플릿 엔진 자체에 대한 호불호가 갈리는게 사실이고, 제가 속한 팀에서도 처음에 걱정들이 많았습니다.

그런데 적용 후 PHP 스크립트를 직접 쓰는것 보다 코드 작성이 훨씬 깔끔하고 그러니 가독성도 좋아서 대부분 만족해 하고있습니다.

kaido / 2019/08/19 09:52:52 / 추천 0

네 정확히 판단 하셨습니다

템플릿엔진으로 해결하는것이 잘못 되었다는것이 아닙니다.

대는 소를 포함한다고 크게 보면 여러가지 이득이 있을 수는 있으나, 소 잡는 칼로 토끼를 잡지 않는다는 말도 있습니다.

엄격한 기준의 xss 필터와 함께 간결한 코드를 원한다면 좋은 선택이 될수 있습니다.

세상에는 완벽한 솔루션이 없고, 최적화한 솔루션은 있습니다.