{{위키데이터 속성 추적}}
'''안전한 입출력 처리'''(Secure input and output handling)는 [[보안 버그]]와 [[취약점 공격]]을 예방하기 위한 안전한 프로그래밍 기법이다.

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

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

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

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

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

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

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

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

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

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

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

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


[[PHP]]에서 이것은 함수 <code>mysql_real_escape_string()</code><ref>{{웹 인용
 |url=http://php.net/mysql_real_escape_string
 |title=mysql_real_escape_string - Manual
 |publisher=PHP
 |date=2012-11-02
 |accessdate=2012-11-08}}</ref> 또는 <code>PDO::quote()</code><ref>{{웹 인용
 |url=http://php.net/manual/en/pdo.quote.php
 |title=PDO::quote - Manual
 |publisher=PHP
 |date=2012-11-02
 |accessdate=2012-11-08}}</ref>를 사용해서 수행될 수 있다.

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

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

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

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

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

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

[[PHP]]에서 이것은 함수 <code>htmlspecialchars()를 통해 수행된다.</code><ref>{{웹 인용
 |url=http://php.net/htmlspecialchars
 |title=htmlspecialchars - Manual
 |publisher=PHP
 |date=2012-11-02
 |accessdate=2012-11-08}}</ref>

== 같이 보기 ==
* [[데이터 확인]]

== 각주 ==
{{각주}}

[[분류:컴퓨터 보안]]
[[분류:보안 소프트웨어]]