방어적 프로그래밍(Defensive programming)은 예상치 못한 입력에도 한 소프트웨어가 계속적 기능 수행을 보장할 수 있도록 고안된 방어적 설계의 한 형태이다. 이 생각은 머피의 법칙이 발현할 가능성을 줄이거나 제거하는 것으로 보일 수 있다. 방어적 프로그래밍은 기법들은 한 소프트웨어가 해롭거나 부주의하게 잘못 사용되어 재앙적 결과를 가져올수도 있을 때 사용된다.
방어적 프로그래밍은 소프트웨어와 소스코드를 아래의 관점에서 향상시키는 한 접근법이다:
방어적 프로그래밍은 때때로 이 버그를 줄이는 접근을 언급하는 컴퓨터 학자들에 의해 안전한 프로그래밍(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 종료 하지 않을 것
// ...
}