보안 문제를 막을 수 있는 방법

문제는 프로그래머의 실수와 오랜 관행이다

Graybored
Orange Scence

--

Google Chrome 환경에선 글씨체가 매끄럽지 않습니다. Internet Explore 9 이상의 브라우저나 Mozlia Firefox로 보시는걸 추천합니다.

최근 발견된 세 종류의 보안 버그는 비밀번호와, 이메일 주소, 금융 관련 정보, 그리고 여러 종류의 민감한 개인 정보를 유출시켰습니다. 이 세 버그의 이름은 각각 OpenSSL의 ‘하트블리드(Heartbleed)’, iOS와 MacOS에서 발생한 버그인 ‘goto fall’, 그리고 마이크로소프트 윈도우즈 익스플로러에서 발생한 ‘Zero-day Exploit’ 입니다. 이 소프트웨어들은 각자 다른 환경에서 발생했지만, 몇 가지 공통점이 있습니다. 그 중에서도 중요한 두 가지의 공통점은 이 프로그램들이 C언어에 의해 씌여졌다는 점, 그리고 프로그래머들의 실수(안전하지 않은 코드의 사용)에 의해 발생했다는 점입니다.

중요한 인터넷 프로그램에 C언어를 사용한다는 것은 박스를 자르려고 Spring-loaded Razor를 사용하는 것과 같습니다. 매우 유용하지만, 자칫하면 여러분의 손가락을 잘라버릴 수도 있죠. 물론 그렇다고 해서 우리가 C언어 사용을 그렇게 빨리 멈출 순 없을 겁니다. —C언어와 C++와 관계된 언어로 만들어진 프로그램들이 많이 쓰이고 있기 때문입니다. 지금도 C언어의 속도 때문에 수많은 프로젝트들이 C언어를 기반으로 만들어지고 있습니다. 물론 그들은 자신들이 C언어의 문제점을 막을 수 있다고 생각하죠.

사람이 만든 것은 완벽하지 않습니다. 그렇기 때문에 우리는 최대한 문제를 발생시키게 하지 않고, 문제가 발생해도 빠르게 고칠 수 있도록 여러가지 정책을 수립하죠. 대표적인 예시가 바로 건축가입니다. 건축가들은 반드시 정부에서 수립한 건축 규정을 지켜야 합니다. 예를 들자면 복도는 최소 어느 정도는 되어야 한다는 것, 그리고 비상탈출구는 언제나 만들어야 한다는 점이죠. 또한 이러한 점이 잘 지켜졌는지 살펴보기 위해 때때로 감독관들을 투입합니다. 따라서 이러한 규정들은 잘 지켜지는 편이죠.

그러나 프로그램 개발 환경에서는 이러한 원칙은 전혀 지켜지지 않고 있습니다. 개발자가 어떤 언어로 프로그램을 개발할지를 결정하는 것은 오랜 관행이고, 심지어 수많은 개발자들은 자신이 직접 만든 신뢰성 테스트를 통해 프로그램의 오작동 여부를 판별합니다. 중소기업들은 신뢰성 테스트만을 전문적으로 할 팀을 조직할만큼의 여유가 없기 때문이죠. 대기업이라고 사정은 크게 다르지 않습니다. 대형 회사에서도 그다지 문제가 없어보이는 프로그램은 테스트 없이 그대로 출시됩니다. 이유는 간단합니다. 버그를 잡는데에 드는 비용이 비싸기 때문이죠. 심지어는 버그를 잡는데에 드는 비용이 소프트웨어를 만드는데에 드는 비용보다 더 비싼 경우도 종종 있습니다.

많은 프로그램 개발자들은 자기가 스스로 만든 신뢰성 테스트를 통해 프로그램의 오작동 여부를 판별합니다. 심지어 대형 회사라고 하더라도, 프로그램이 잘 작동하는 것처럼 보이면 테스트도 하지 않죠.

그럼 어떻게 이 문제를 해결할 수 있을까요? 정답은 간단합니다. 프로그램을 감시하는 감독관을 만들되, 비용이 들지 않는 감독관을 만드는 것이지요. 단 여기에는 조건이 하나 있습니다. ‘감독관’은 사람이 되어선 안 됩니다. 아니면, 사람만이 감독관이 되어선 안됩니다. 이는 하트블리드 사태에서도 잘 드러나는데, OpenSSL은 구글의 보안 엔지니어와 최고의 IT 보안 기업인 코데노미콘(Codemonicon)에 의해 보안 업데이트가 이루어졌음에도 불구하고 버그를 찾아내지 못했기 때문이죠. 이는 이 프로그램의 개발에 참여한 수많은 사람들 역시 마찬가지였습니다.

그렇다면, 무엇이 프로그래밍의 ‘감독관’이 되어야 할까요? 정답은 간단합니다. 바로 ‘프로그래밍 툴’ 그 자체입니다. 프로그래밍 툴 자체가 안전하지 않은 코드를 사용하면 프로그래머에게 주의를 주는 것이지요. 이는 1998년에의 사례에서도 두드러집니다. “gets()”코드의 취약점을 이용한 세계 최초의 웜바이러스가 만들어진 이후, 유닉스 운영체제는 만약 프로그램이 “gets()”코드를 사용한 프로그램이 실행되는 경우 보안 경고문을 띄웠고, 이후 프로그래머들은 “gets()”코드를 쓰지 않거나, 혹은 쓰더라도 프로그램에서 gets()코드를 삭제하게 된 것이죠.

이와 비슷한 접근 역시 제 2의 하트블리드 버그, 혹은 제 2의 ‘goto fall’과 같은 버그를 막을 수 있을 것입니다. 또한 최근의 소프트웨어 개발 도구들은 대부분 이러한 장치를 지니고 있습니다. 예를 들자면 코드가 엉성하게 짜여있거나 메모리 버그가 발생하게 코드가 짜인 경우엔 경고문을 출력하는 것 말이죠. 그러나 이러한 장치들은 대부분 기본적으로 ‘꺼져’있습니다. 이유는 간단합니다. 프로그래머들이 이러한 장치들을 귀찮게 생각할 것이라는 이유 때문이죠. 심지어 이러한 버그 탐지 장치를 따로 파는 경우도 존재합니다. 때문에 수많은 개발자들이 이러한 장치에 대해서 전혀 모르고, 이러한 장치들을 사용하지 못하는 경우가 왕왕 발생하는 것이죠.

인터넷을 더욱 안전하게 만들기 위해선, 이러한 장치들이 반드시 기본적으로 프로그램에 탑재되어 있어야 할 것입니다. 또한 이러한 장치 역시 ‘엄격하게 버그 확인’모드가 기본적으로 켜져있어야겠죠. 그리고 이러한 장치들은 보통 C#나 자바에서 더욱 잘 작동하기 때문에, 새로운 프로젝트는 가급적이면 C나 C++ 대신 자바나 C#로 시작해야 할 것입니다.

프로그래머들은 실수를 연발할 수 있는 평범한 인간일 뿐입니다. 소프트웨어 개발 회사들은 이러한 사실들을 잘 인지하고, 지금이라도 위와 같은 대책을 수립하여야 할 것입니다.(MIT Tech Review)

--

--