안전한 입출력 처리

안전한 입출력 처리(Secure input and output handling)는 보안 버그와 취약점 공격을 예방하기 위한 안전한 프로그래밍 기법이다.

입력 처리 
입력 처리는 애플리케이션이나 서버, 다른 컴퓨팅 시스템이 사용자나 클라이언트 또는 네트워크에서 들어오는 입력을 어떻게 다루는지에 관한 것이다.

안전한 입력 처리는 종종 코드 인젝션, 디렉토리 순회 등과 관련된 취약점들을 예방하기 위해 요구된다.

입력 확인 
사용자 입력을 확인하는 것은 사용하기 전에 입력이 안전한지 보장하는 것이다.

이것을 가능하게 하는 가장 안전한 방식은 의심스러운 입력을 종료하고 실행을 끝내야 하는지를 결정하는 화이트리스트 전략을 사용하는 것이다.

화이트리스트와 블랙리스트 
컴퓨터 보안에서, 개발자가 안전하다고 완벽히 확신하는, 알려진 좋은 입력이 있다. 또한 나쁜 문자들로 알려진 것들도 존재한다(코드 인젝션을 유발할 수 있는). 이것에 기반하여 어떻게 입력이 관리되어야 하는지에 대한 두 가지의 다른 접근법이 존재한다.
 화이트리스트 (좋다고 알려진 것들). 하이트리스트는 좋은 입력으로 알려진 것들의 리스트이다. 이것은 기본적으로 "A, B 그리고 C는 좋다"고 말하는 리스트이다.
 블랙리스트 (안 좋다고 알려진 것들). 블랙리스트는 안좋은 입력으로 알려진 것들의 리스트이다. 이것은 기본적으로 "A, B 그리고 C는 좋지 않다"고 말하는 리스트이다.
보안 전문가들은 블랙리스트가 우연히 나쁜 입력을 안전하게 다룰 수 있으므로 화이트리스트를 선호하는 경향이 있다. 그러나 어떤 경우에 화이트리스트 솔루션은 쉽게 구현되지 않을 수 있다.

입력 문제들에 대한 종료/정지/중단 
이것은 매우 안전한 전략이다. 만약 예상치 않은 문자들이 입력에 발생하면, 실행을 중단한다. 그러나 만약 좋지 않게 구현되었다면, 공격자가 시스템에 예상치 않은 입들을 뿌려서 시스템에 대한 서비스 거부 공격에 이를 수 있다.

입력 필터 
입력을 필터링하는 것은 입력 문제들에 대한 종료/정지/중단 보다 덜 전통적인 보안 원리로 사용된다.
 엔드 사용자에게 필터 접근방식의 장점은 보안 메커니즘이 종종 덜 거슬리는 방식으로 행동한다는 점이다. 예를 들면 만약 "*" 이 불법이라면,  "I ***LOVE*** you"는 "I LOVE you"가 돼서, 흔한 경우는 아니지만 이상하게 받아들여질 수 있다.
 필터 접근방식의 단점은 옳게 만들기가 좀 어렵다는 점이다. - 실제로 많은 애플리케이션들이 코드의 한 부분에만 적용된 필터를 갖지만, 프로그래머는 우연히 다른 위치에서 필터링되지 않은 입력을 사용할 수 있다.

필터 입력: 자동 오염 검사 
몇몇 프로그래밍 언어들은 오염 검사를 내장 지원한다. 이러한 언어들은 사용자 인풋에서 가져온 변수가 위험하게 사용될 때마다, 컴파일 타임 또는 런타임 예외를 던진다.

필터 입력: 화이트리스트 필터들 
예시:
 모든 문자들이 A-Za-z 여야 한다는 입력 필터는 유닉스 애플리케이션을 셸 인젝션으로부터 보호하기 위해 사용된다.
 공격자들은 셸 인젝션을 시도하기 위해 입력 ; ls -l / 를 공급한다.
 필터는 입력에 적용된다.
 문자열  ; - / 는 화이트리스트에 없기 때문에 필터에 의해 던져진다.
 문자열 lsl 는 화이트리스트에 존재하기 때문에 필터에 의해 받아들여진다.
 오직 안전한 입력만 남게 되기 때문에 익스플로잇 시도는 실패한다.

필터 입력: 블랙리스트 필터들 
만약 [:;.-/]이 포함된 문자열이 좋지 않다고 알려졌다면 ls -l / 는 받아들여 지지만, 원래 입력은 ls l 로 대체된다(;-/ 는 던져진다). 이 전략은 여러 문제들을 갖는다.
 이것은 알려지지 않은 위협을 보호할 수 없다. 개발자가 고려하지 않은 다른 "안좋은" 입력들이 존재할 것이다.
 이것은 미래의 위협을 보호할 수 없다. 입력들이 현재는 안전하지만 사용된 언어의 변화에 따라 미래에는 위험할 수 있는 표현을 포함하고 있을 수 있다. 예를 들면, 유닉스 명령줄 보안 필터는 C 셸에 대한 공격을 막기 위해 고안되었지만, 만약 소프트웨어가 배시를 사용하는 환경으로 바뀐다면 위험해질 것이다.

암호화(인코딩) 입력 
악의적인 입력들을 갖고 있기 위해서, 입력들은 암호화될 필요가 있다.

SQL 인코딩:  ' OR 1=1 --' 는 \ \'\ OR\ 1\=1\ \-\-'로 암호화 된다.

PHP에서 이것은 함수 mysql_real_escape_string() 또는 PDO::quote()를 사용해서 수행될 수 있다.

다른 해결법들 
무슨 프로그래밍 언어가 사용되는지 그리고 어떠한 종류의 코드 인젝션을 보호할지에 따라 다른 해결책들이 존재한다.

특히, SQL 삽입을 예방하기 위해서는, parameterized queries (또한 prepared statements 와 bind variables로 알려진)가 코드 명료성과 수행 능력을 향상시킬 뿐만 아니라, 보안을 향상시키는 데 유용하다.

출력 처리 
출력 처리는 애플리케이션, 서버 또는 시스템이 출력을 처리하는 방식이다(예를 들면 HTML, 프린팅, 로깅...). 출력이 종종 사용자, 클라이언트, 네트워크, 데이터베이스 등에서 제공된 입력을 포함한다는 점을 숙지하는 것이 중요하다.

안전한 출력 처리는 주로 사이트 간 스크립팅 취약점을 예방하는 것과 관련있지만, 또한 비슷한 분야에서도 중요하다고 판명될 수 있다(예를 들면 마이크로소프트 오피스 문서와 몇몇 API들을 생성한다면, 출력 관리는 잠재적으로 매크로 삽입을 예방할 필요가 있다).

암호화 출력 
"암호화"는 출력할 내용을 처리하므로, 어느 잠재적으로 위험한 문자열들도 안전하게 만들어질 수 있다. 일반적으로 안전한 문자로 알려진 문자열들은 종종 그대로 남는다. 간단한 암호화는 a–z, A–Z 그리고 0–9를 내버려 둘 것이다. 다른 문자열들은 예상치 않은 방식으로 해석되며, 적절하게 암호화된 표현으로 대체된다.

HTML 인코딩: <script>는 &lt;script&gt;로 인코딩된다.

PHP에서 이것은 함수 htmlspecialchars()를 통해 수행된다.

같이 보기 
 데이터 확인

각주 

컴퓨터 보안
보안 소프트웨어