방어적 프로그래밍

방어적 프로그래밍(Defensive programming)은 예상치 못한 입력에도 한 소프트웨어가 계속적 기능 수행을 보장할 수 있도록 고안된 방어적 설계의 한 형태이다. 이 생각은 머피의 법칙이 발현할 가능성을 줄이거나 제거하는 것으로 보일 수 있다. 방어적 프로그래밍은 기법들은 한 소프트웨어가 해롭거나 부주의하게 잘못 사용되어 재앙적 결과를 가져올수도 있을 때 사용된다.

방어적 프로그래밍은 소프트웨어와 소스코드를 아래의 관점에서 향상시키는 한 접근법이다:

  • 일반적 품질 - 소프트웨어 버그와 문제의 수를 줄인다.
  • 그 소스 코드를 이해하기 쉽게 만든다 - 그 소스 코드는 읽기 쉽고 이해하기 쉬워서 코드 리뷰(code audit)에서 승인된다.
  • 그 소프트웨어가 예상치 못한 입력들이나 사용자의 동작들에도 예상 가능한 방식으로 동작하도록 한다.

안전한 프로그래밍

[편집]

방어적 프로그래밍은 때때로 이 버그를 줄이는 접근을 언급하는 컴퓨터 학자들에 의해 안전한 프로그래밍(secure programming)으로 불린다. 소프트웨어 버그는 잠재적으로 코드 주입, 서비스 거부 공격 또는 다른 공격을 위한 크래커에 의해 이용당할 수 있다.

방어적 프로그래밍과 보통 습관들 사이의 차이는 모든 가능한 에러 상태들을 다루고자 시도하는 프로그래머가 실제로는 그것을 거의 가정하지 않는다는 것이다. 줄여 말하면, 그 프로그래머는 한 특별한 함수 호출 또는 라이브러리가 적대적이게 동작할 수 있다고 가정하지 않고 그것을 그 코드안에서 다룬다. 한 예는 다음과 같다:

int risky_programming(char *input){
  char str[1000+1];     // 널 문자를 위해 하나 추가
  // ...
  strcpy(str, input);   // copy input
  // ...
}

이 함수는 입력이 1000 문자를 넘을 때 충돌을 일으킬 것이다. 몇몇 미숙한 프로그래머들은 사용자들이 그런 긴 입력을 넣지 않을 것이라고 가정하면서 이것이 별 문제가 아니라고 느낄지도 모른다. 한 방어적 프로그래밍을 실천하는 프로그래머는 그 버그를 허용하지 않았을 것이다, 왜냐하면 만약 그 응용 프로그램이 한 알려진 버그를 포함한다면 머피의 법칙은 그 버그가 실제 사용 시에 발생할 것이라고 말하기 때문이다. 이 특정 버그는 버퍼 오버플로우이용하여 일으킬 수 있는 한 취약성을 재연한다. 여기 이 예제에 대한 한 해결 방법이 있다.

int secure_programming(char *input){
  char str[1000];
  // ...
  strncpy(str, input, sizeof(str)); // str의 길이를 초과하지 않도록 입력(input) 복사
  str[sizeof(str) - 1] = '\0';              // 만약 strlen(input) == sizeof(str) 여도 strncpy가 NULL 종료 하지 않을 것
  // ...
}

같이 보기

[편집]

추가 문헌

[편집]
  • William R. Cheswick and Steven M. Bellovin, Firewalls and Internet Security: Repelling the Wily Hacker ISBN 0-201-63357-4http://www.wilyhacker.com/
  • 스티브 맥코넬저, 서우석 역, Code Complete (2nd edition), 8장 방어적인 프로그래밍 ISBN 978-89-5674-256-4

외부 링크

[편집]