상세 컨텐츠

본문 제목

Codeigniter3 XSS filtering issue

Programing/CodeIgniter

by 호짱 HoZang 2019. 8. 13. 00:33

본문

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

 

Some text was removed while xss filtering in codeigniter

Removed text is '% 33', '% 40'. (single quote is not included) $text = "% 33"; $xss_text = $this->input->post($text, TRUE); echo $xss_text; // result is 3 and @

stackoverflow.com

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

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

 

CodeIgniter - why use xss_clean

if I'm sanitizing my DB inserts, and also escaping the HTML I write with htmlentities($text, ENT_COMPAT, 'UTF-8') - is there any point to also filtering the inputs with xss_clean? What other benefits

stackoverflow.com

 

그러면 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

 

Input Class ‐ 코드이그나이터 3.0 한글매뉴얼

CodeIgniter는 POST, COOKIE 혹은 SERVER 아이템을 가져오기 위해서 3가지 헬퍼함수를 제공합니다. 각 아이템들을 직접 가져오는 것보다($_POST['something']) 헬퍼를 사용하면 더 좋은 이유는, 헬퍼가 아이템이 세팅되어 있는지를 먼저 체크하고 세팅되어있지 않다면 FALSE를 반환하기 때문입니다. 아이템이 존재하는지 먼저 검사하고 처리할 필요가 없어집니다. 다시말하면, 일반적으로 여러분안 아래와 같이 프로그램할 것입니다: $

www.ciboard.co.kr

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

<?php $variable = "<p>호짱의 개발 블로그</p>"; ?>
<?=htmlentities($variable)?>
<?=htmlspecialcharacters($variable)?>
// 출력
// <p>호짱의 개발블로그</p>

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

그런데 Twig(https://twig.symfony.com/) 같은 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

 

kenjis/codeigniter-ss-twig

A Simple and Secure Twig integration for CodeIgniter 3.x - kenjis/codeigniter-ss-twig

github.com

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

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

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

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

 

코드이그나이터에서 블레이드 템플렛 사용하기

코드이그나이터에서 블레이드 템플렛 사용하기 우선 블레이드를 라라벨 없이 사용가능한 컴포넌트를 받아 오토로드 합니다. 컴포저가 설치됐다는 가정 하에 커멘드라인에서 컴포넌트 설치. composer require dunca..

khanorder.tistory.com

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

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

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

이렇게 말이죠~

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

관련글 더보기

댓글 영역