입력 검증의 두가지 방법 화이트리스트, 블랙리스트 비교

웹어플리케이션은 웹의 특성상 무방비상태로 노출되어 있고, 항상 해커의 공격대상이 된다. 해커의 공격을 막는 여러 방법 중 제일 기본이 되는 건 사용자의 입력을 검증하는 것이다. 서버단에서는 반드시 검사를 해야하고, 브라우져단에서도 자바스크립트등을 써서 일차검증을 하는게 사용 편이성 증대 및 서버부하를 줄일 수 있다.

사용자 입력검증을 하는 방법에는 어떤게 있고, 어떤 방법을 써야 바람직한가에 대한 내용이 “웹애플리케이션 해킹대작전“이란 책에 자세히 소개되어 있어서 인용한다.

입력검증을 위한 방법은 두 가지가 있다. 즉 화이트리스트(white-list)와 블랙리스트(black-list)를 이용하는 방법이다. 화이트리스트는 허용 가능한 입력 값에 대한 리스트이고, 블랙리스트는 허용되지 않는 입력 값에 대한 리스트이다. 그런데 어떤 것을 이용하는 것이 더 나은가? 허용가능 리스트를 만들 것인가, 아니면 허용해선 안 되는 라스트를 만들 것인가?

보안에 대해서 잘 아는 많은 프로그래머들은 블랙리스트가 정답이라고 생각한다. 하지만 결국에는 그것이 틀렸다는 것을 알게 된다. 그런데 왜 그렇게 생각하는 것을 막을 수 없는 것일까? 사실, 어떤 특정한 공격에 포함되어 있는 특정문자(예를 들면, ‘<>–;)나 문자열 일부분(예를 들면 스크립트 태그, SQL문장)을 입력 값에서 필터링 하는 것이 더 쉬운 경우가 많다.

하지만 블랙 리스트를 이용하는 방법은 근본적으로 위험성을 내포하고 있다. 그 중에서도 가장 심각한 것은, 블랙리스트에 모든 것이 포함되어 있다고 확신하는 것이다. 블랙리스트에서 빠진 항목은 검증루틴을 통과하게 된다. 필터링되어야 함에도 불구하고 필터링되지 못하는 것이다. 즉 검증루틴은 악의적인 목적의 입력데이터를 검출해 내지 못할 수 있다.

모든 문자가 숫자 형태뿐만 아니라 브라우져가 받아 들일 수 있는 다른 종류의 인코딩된 형태로 표현될 수 있다고 가정해보자. 공백 문자는 공백으로 표현되거나 ‘+’ 또는 ‘%20’으로 표현될 수 있다. 따라서 개발자는 잘못된 문자뿐만 아니라 잘못된 문자가 인코딩된 문자까지도 모두 필터링해야 한다. 이것은 문자는 물론이고 문자열인 경우에도 마찬가지다.

아직까지 알려지지 않은 공격의 경우에는 어떨까? 공격자가 점점 영리해짐에 따라 블랙리스트는 계속 업데이트되어 왔고 앞으로도 계속 추가돼야 한다. 따라서 블랙리스트보다는 화이트리스트를 이용하는 편이 훨씬 낫고 수월하다. 화이트리스트는 애플리케이션에 입력되는 데이터를 다양하게 분류(문자, 숫자, 알파벳 문자, 구두점 등)해서 관리하고 각 분류별 패턴을 기반으로 검증을 수행한다. 예를 들어 미국이 우편번호는 5개 꼬는 9개의 문자로 만들어져야 하고, 이메일 주소는 @문자로 구분되고 알파벳 문자로 표기한다.

화이트리스트를 이용하면 사용자입력이 올바른지 그릇된 것인지 구분해 낼 수 있다. 그런데 여기서 한가지 의문이 생긴다. 잘못된 입력데이터는 수정해야 하는가? 답은 간단하다. “아니오.” 입력데이터를 수정하면 할수록 입력검증의 소용돌이에 점점 더 깊이 빠져들 뿐이다. 예를 들면, 문자열 “<scr<script>ipt>”에서 문제가 되는 부분(<script>태그)을 찾아서 제거했는데도 불구하고 문자열은 다시 문제가 되는 부분(<script>)을 포함하게 된다. 블랙리스트를 이용해서 검증하는 경우에는 대부분 이런 교묘한 트릭이 가능하다.

애플리케이션에 올바른 데이터가 입력되는지 검사해서 그렇지 않다면 에러를 발생시키고 동작을 멈추는 것이 가장 좋은 방법이다.