본문 바로가기

한땀한땀/Microsoft

Trustworthy Computing

5년 동안 더 안전한 소프트웨어를 구축하면서 얻은 교훈
Michael Howard

이 기사에서 다루는 내용:
  • 나이별로 코드 우선 순위 설정
  • 분석 도구 및 자동화 사용
  • 여러 각도에서 위협 관찰
  • 교육의 중요성
이 기사에서 사용하는 기술:
5년 전 Bill Gates가 더 안전한 소프트웨어 구축의 중요성에 대해 설명한 메모를 모든 Microsoft 직원들에게 전달한 이후 Microsoft 직원들은 각자 자신이 맡은 제품의 보안을 강화하기 위해 노력했고 이 과정에서 더 안전한 소프트웨어를 구축하는 데 필요한 요소에 대해 많은 것을 배웠습니다.
보안은 정적인 분야가 아닙니다. 공격자는 공격하면서, 방어자는 방어하면서 각자 상대방의 기술에 대해 더 많은 부분을 익히고 이에 따라 보안도 끊임없이 진화합니다. 보안은 군비 확장 경쟁입니다. 공격자보다 앞서 나가고 공격을 예견하기 위해 우리와 같은 방어자들은 과거의 실수로부터 교훈을 얻어 사용자가 피해를 입지 않도록 보호하는 더 나은 방법을 만들어야 합니다.
그렇다면 지난 5년 동안 Microsoft가 얻은 교훈은 무엇일까요? 사실 이러한 교훈의 대부분은 지극히 당연한 내용입니다. 그러나 당연한 사실이라 해도 종종 누군가가 나서서 강조해야 할 필요가 있고, 여기에서 다룰 내용도 마찬가지입니다.

코드만의 문제가 아니다.
소프트웨어 업계, 더 정확히 말해 소프트웨어 품질 업계는 올바른 코드를 작성하는 데 집중하고 있습니다. 필자는 이에 대해 이의는 없지만 상당수의 보안 취약점은 코딩과는 전혀 관계가 없습니다. 많은 보안 취약점의 원인은 설계 문제입니다. 코드에서 보안 문제를 찾는 데만 집중한다면 취약점의 한 범주를 통째로 놓치게 됩니다. 이러한 사실이 Microsoft가 SDL(Security Development Lifecycle) 프로세스에서 위협 모델링과 공격 취약 영역 분석을 의무화하는 이유 중 하나입니다. 위협 모델링은 제품의 설계 취약점을 식별하고 완화하는 데 도움이 되는 분석 기술입니다. 공격 취약 영역 분석은 소프트웨어 제품에서 신뢰할 수 없는 사용자(로컬이든 원격이든)에게 노출되는 부분에 집중합니다. 공격 취약 영역이 넓은 제품은 좁은 제품에 비해 더 많은 코드가 신뢰할 수 없는 사용자에게 노출됩니다. 자세한 내용은 msdn.microsoft.com/msdnmag/issues/04/11/AttackSurface를 참조하십시오.
Microsoft 보안 공지 MS07-029(microsoft.com/technet/security/Bulletin/MS07-029.mspx 참조)에 설명된 DNS RPC 버퍼 오버런 취약점은 공격자가 감염된 시스템을 완전히 장악할 수 있게 해줍니다. 이 경우에는 확실히 코드 문제가 있습니다. 하지만 이 코드에는 원래 관리자만 액세스할 수 있어야 하는데 익명 및 원격 사용자도 액세스할 수 있었습니다. 따라서 이 문제는 코드 취약점과 디자인 취약점이 결합된 형태였습니다. 필자는 SDL 블로그(blogs.msdn.com/sdl/archive/2007/06/28/lessons-learned-from-ms07-029-the-dns-rpc-interface-buffer-overrun.aspx 참조)에서 이 취약점을 분석했습니다.
교훈 위협 모델을 필수적으로 구축하여 잠재적인 설계 취약점을 밝혀내고 소프트웨어의 공격 취약 영역을 확인해야 합니다. 또한 모든 실질적 위협을 완화하고 공격 취약 영역을 가능한 한 최소화해야 합니다.

오래된 코드부터 수정하라.
코드를 검토할 때 필자는 취약 가능성에 따라 코드에 순위를 매기는 방법을 사용합니다. 필자는 IEEE Security & Privacy에 "보안 코드 검토를 위한 프로세스"라는 제목으로 코드 검토의 우선 순위를 설정할 때 필자가 사용하는 기준에 대해 설명한 기사를 썼습니다. 이 문서의 링크는 필자의 블로그인 blogs.msdn.com/michael_howard/archive/2006/08/01/686029.aspx에 있습니다.
첫 번째 우선 순위는 오래된 코드입니다. 오래된 코드는 최신 코드에 비해 보안 취약점이 더 많을 가능성이 훨씬 높기 때문입니다. 위협은 끊임없이 진화합니다. 오래된 코드(불과 몇 년 전에 작성된 코드까지 포함)는 현재와 다른 위협 상황에서 작성되었습니다. 또한 오래된 코드를 작성하는 데 사용된 기술에는 최신 방어 기법과 최적의 방법이 적용되어 있지 않습니다. 마찬가지로 기존 코드는 보안 성능이 떨어지는 과거의 라이브러리를 사용하여 구축되었습니다. 마지막으로, 과거에는 대부분의 개발자들에게 보안 전문 지식이 거의 없었으므로 오래된 코드는 상황 인식이 결여된 상태에서 작성되었습니다.
필자의 조언은 간단합니다. 즉, 모든 오래된 코드에서 보안 취약점을 직접 검토하라는 것입니다. 사실 이는 Microsoft에서 SDL의 보안 적용 단계를 수행하는 목적입니다. SDL의 기본적인 목표는 개발자가 제품에 새로운 취약점을 추가할 가능성을 낮추는 것이지만, 보안 추진은 개발 팀이 의무적으로 오래된 코드에서 문제점을 찾도록 하기 위해 고안되었습니다.
코드 복잡성, 코드 줄 수, 코드 변동률 등 다른 어떤 측정 기준도 코드 검토에 우선 순위를 설정하는 데 있어 이만큼 중요하지는 않습니다. 잠재적 취약점의 밀도에 대한 첫 번째 지표는 다름아닌 코드의 나이입니다.
교훈 모든 소스 코드 파일을 확인하고 나이별로 등급화합니다. 여기서 나이란 코드가 “태어난” 날짜를 기준으로 합니다. 정적 분석을 수행하고 가장 오래된 코드부터 시작하여 수동으로 코드를 검토합니다.

비활성화, 삭제, 지원 중단의 수순을 따르라.
종종 현재 위협 상황에서 볼 때 어떤 기능의 보안이 부족한 경우가 있습니다. 이 기능은 지난 몇 년 동안은 문제 없었지만 코드 취약성이 아닌 컴퓨터 환경의 변화로 인해 지금은 더 이상 안전하지 않게 되었습니다.
이와 같은 경우의 좋은 예는 인쇄 상태를 표시하고 짧은 메시지를 전송하여 다른 사용자의 화면에 팝업 창을 띄우는 Windows®의 경고 서비스입니다. 이 서비스는 매우 빠르게 스팸 메커니즘화되었고 Microsoft는 Windows XP SP2에서 이 기능을 기본적으로 비활성화하기로 결정했으며, 이후 Windows Vista®에서는 이 서비스를 완전히 제거했습니다.
또 다른 좋은 예는 구식 IPX 및 SPX 프로토콜입니다. (물론 IPv4 역시 오래된 프로토콜이며 나름의 문제점을 안고 있습니다.) Windows Vista에서 Microsoft는 오래된 코드에다 사용되지도 않는 Microsoft® Client for NetWare Networks에 대한 지원을 제거했습니다.
앞으로도 Microsoft는 신중하게 오래된 기능들을 제거해 나갈 것입니다. 일부 사용자는 기능에 의존하므로 위험과 유용성 사이의 균형이 중요합니다.
교훈 장기적으로 보안 문제가 될 수 있는 오래된 기능을 찾고 이러한 기능을 제거할 계획을 세웁니다. 첫 번째 단계는 기능을 계속 제공하되, 기본적으로 비활성화하는 것입니다. 그런 다음 제품의 다음 버전에서 해당 기능을 완전히 제거하고 꼭 필요한 사용자를 위해 웹 다운로드 형태로 제공합니다. 마지막으로 기능에 대한 지원을 중단합니다. 고객에게 이러한 사실을 알려야 한다는 점을 유의하십시오.

도구도 중요하다.
예전에 필자는 도구에 대해 상당히 비판적이었습니다. 정확히 말하자면 도구 자체가 아니라 일부 개발자들의 도구에 대한 지나친 의존에 대해서지요. 필자가 말하는 도구란 정적 코드 분석, 이진 분석을 비롯해 보안 취약점을 발견하는 데 도움이 되는 것들입니다. 세월이 흐르면서 필자는 이러한 자세를 누그러뜨렸습니다.
코드의 분량이 많다면, 예컨대 백만 줄 분량의 코드라면 모든 코드를 직접 검토하기란 매우 어려운 일입니다. 도구는 많은 양의 코드를 신속하게 분석할 수 있다는 측면에서 유용합니다. 그러나 도구는 인간의 지적 능력을 대신하지는 못하며 많은 경우 가양성(false positive) 및 가음성(false negagtive) 판정을 최대한 낮추는 데 신경 쓰느라 취약점을 놓칩니다. 또한 솔직히 말하자면 많은 보안 분석 도구들은 너무 많은 오류와 경고를 쏟아내기 때문에 진짜 버그와 그렇지 않은 것을 판별하기가 매우 어렵습니다.
물론 문제의 수가 너무 많다는 것이 도구의 출력 내용을 무시해도 좋다는 의미는 아닙니다. 보안 취약점의 원인 분석을 수행할 때 Microsoft에서는 항상 문제가 도구를 통해 발견되지 않은 이유를 찾습니다. 가능한 이유는 세 가지입니다. 즉, 도구가 취약점을 찾지 못했거나 찾긴 했지만 문제를 잘못 분류하여 우선 순위를 낮게 설정했거나 도구는 문제를 제대로 찾았지만 사람이 잘못 분류한 경우입니다. 이 분석을 통해 시간 경과에 따라 도구와 교육을 세부적으로 조정할 수 있습니다.
분석 도구는 코드의 잠재적인 보안 취약점을 확인하는 데에도 매우 유용합니다. 예를 들어 각각 100,000 줄의 C++ 코드로 이루어진 두 개의 제품이 있다고 가정해 보겠습니다. 각 코드 기반에서 도구를 실행합니다. 이 예에서는 사용하는 도구가 /W4 및 /analyze 컴파일러 스위치라고 가정합니다. 첫 번째 코드 기반에서는 121개의 /W4 경고와 19개의 /analyze 경고가 발생하고 두 번째 코드 기반에서는 235개의 /W4 경고와 65개의 /analyze 경고가 발생합니다. 둘 중 어떤 코드에 더 많은 검토가 필요할까요?
마지막으로, 도구는 체크 인 전에 새로운 코드 또는 수정된 코드에서 실행하면 코드 경찰관 역할을 수행하면서 프로세스 초기에 특정 부류의 버그를 잡아낼 수 있으므로 매우 유용합니다.
교훈 분석 도구는 코드에 얼만큼의 검토가 필요한지 판단하는 데 도움이 됩니다. 또한 분석 결과를 사용하여 전체적인 코드의 위험성을 확인할 수 있습니다. 체크 인 시에 도구를 사용하여 조기에 버그를 잡을 수 있습니다. 또한 새로운 문제를 신속히 처리할 수 있도록 도구를 자주 실행하십시오. 몇 개월마다 한 번씩 도구를 실행한다면 한 번에 수백 개의 경고를 처리해야 하는 경우도 발생합니다.

자동화하라!
보안 개선 계획의 시작 부분에는 수동 코드 검토, 수동 설계 검토 등 많은 양의 수작업이 필요합니다. 작업의 능률을 높이려면 가능한 한 많은 프로세스를 자동화해야 합니다.
필자의 팀은 다수의 맞춤형 도구를 구축하고, 중앙 보안 팀이 도구의 출력을 검토할 수 있도록 도구에서 데이터를 수집하기 위한 내부 웹 사이트를 만들었습니다. SDL 개선 방안을 제안하려면 이 제안에는 개선을 자동화하는 방법도 포함되어야 합니다. 자동화에 대한 가장 주요한 동기 부여 요소는 확장성과 지속적인 사용입니다. 코드의 양이 많다면 자동화가 필요합니다. 또한 프로세스의 일부를 계속해서 반복하려는 경우에도 확실히 자동화를 채택해야 합니다.
교훈 가능한 경우 항상 자동화를 추진합니다. 코드를 검색하고 보안 전문가가 분석할 수 있도록 중앙 사이트에 결과를 업로드하는 도구를 구축하거나 구매합니다.

보안 취약점을 완전히 없애기란 불가능하다.
인정하기 싫은 진실은 보안 취약점의 수를 0으로 만들기란 불가능하다는 점입니다. Windows Vista의 첫 번째 보안 업데이트를 발표하던 때가 생각납니다. 일부 사용자는 Microsoft가 Windows Vista에서 보안 문제를 해결했다고 주장한 것으로 믿고 있었기 때문에 이 업데이트에 놀랐습니다. 우선 필자는 Microsoft에서 그런 주장을 했다는 사람을 알지 못합니다. 그리고 보안 취약점의 수를 0으로 만들기란 절대 불가능합니다.
보안 취약점이 전무하다면 좋겠지만 그렇게 할 수 있다고 생각한다면 오산입니다. 기술 분야는 항상 변화하고 위협은 움직이는 표적이며 보안 연구는 지속적으로 수행됩니다. 앞서 보안은 군비 확장 경쟁이라고 말했습니다. 우리가 제품에 방어선을 추가하면 공격자는 여기에 적응합니다.
오늘은 코드에 취약점이 전혀 없는 것처럼 보일 수 있지만 내일이면 새로운 유형의 취약점이 발견되면서 상황이 완전히 바뀔 수 있습니다. 예를 들어 2003년 10월 15일 Microsoft는 Microsoft Exchange 5.5에 포함된 Outlook® Web Access의 XSS(사이트 간 스크립트) 취약점을 수정했다는 보안 공지를 발표했습니다. 이듬해 3월 4일 Sanctum(이후 Watchfire에 인수되어 지금은 IBM에 합병됨)은 HTTP 응답 분할로 불리는, 사이트 간 스크립트와 비슷한 새로운 취약점에 대한 문서를 발표했습니다. 6개월 후 Microsoft는 Microsoft Exchange 5.5의 Outlook Web Access에 대한 HTTP 응답 분할 취약점을 수정하는 새로운 보안 업데이트를 발표했습니다. 어떻게 된 것일까요? 간단히 설명하자면 첫 번째 공지가 발표될 시점에는 응답 분할 문제가 드러나지 않았지만 주변 상황이 변화된 것입니다.
교훈 보안 취약점을 줄이는 것이 목표이며, 새로운 기술과 취약점을 찾는 공격자가 존재하는 한 보안 문제를 완전히 없애기란 불가능하다는 사실을 조직 내의 사람들이 인지하도록 합니다.

보안은 끝없는 전쟁이다.
“보안 문제는 끝났습니다. 문제를 해결했습니다”라고 말할 수 있는 날은 결코 오지 않습니다. 이는 앞서 살펴본 관점의 연장이지만 보는 각도는 약간 다릅니다. 엔지니어에 대한 지속적인 교육은 매우 중요한 부분입니다. 이를 실천하지 않으면 시간이 지남에 따라 기술이 녹슬고 위기감도 느슨해집니다. 보안은 불가결한 요소이며 시스템 보호는 그 무엇보다 중요합니다. 앞서 언급했듯이 새로운 위협과 취약점은 계속해서 발견되므로 보안은 언제나 끝나지 않는 업무로 취급해야 합니다.
또한 보안은 더 이상 특별한 것이 아니라는 점도 인식해야 합니다. 보안은 업무 수행의 한 부분일 뿐입니다.
교훈 엔지니어에게 지속적인 교육을 제공하고 보안 문제 처리의 중요성을 항상 인식하도록 합니다.

보안에 완벽한 방법은 없다.
사람들은 “SDL의 가장 중요한 요소는 무엇입니까?”라는 질문을 자주 합니다. 답은 모든 것입니다. SDL의 한 부분이 유용하지 않다고 판명된다면 그 부분은 SDL에서 제외될 것입니다. SDL의 모든 부분은 보안 취약점 감소로 이어집니다. 누군가가 정적 분석 도구 실행 또는 교육과 같은 하나의 마법과 같은 방법으로 보안 문제를 해결할 수 있다고 말한다면 이 사람은 보안 기반에서 놓치는 부분이 있음을 의미합니다. 물론 정적 분석 도구는 유용하고 사용자 교육도 필수적이지만 그것만으로는 부족합니다. 보안은 철저해야 하며 프로세스의 일부분이어야 합니다.
교훈 가능한 모든 각도에서 보안을 다루고 있는지 확인하십시오. 그렇지 않은 경우 프로세스를 변경해야 합니다!

“많은 검토자” 이론은 옳다!
유명한 공개 소스 지지자인 Eric Raymond는 "충분히 많은 사람들이 검토한다면 모든 버그를 쉽게 잡을 수 있다"고 말했습니다. 이 말은 맞습니다. 그러나 필자는 간단명료한 이 문장이 중요한 점을 놓치고 있다고 생각합니다. 여기에는 "이러한 검토자들이 동기 부여가 되어 있고 교육을 받았다면”이라는 조건이 붙어야 합니다.
Microsoft는 직원들에게 프로세스 개선 사항 채택을 요구할 수 있습니다. 이러한 요건이 업무의 일부이기 때문입니다. 이것이 동기입니다. Microsoft는 실제 학습, 실험실, 온라인 학습 등 다양한 형식의 교육을 제공합니다. 따라서 엔지니어들이 보안 분야의 최신 상황에 항상 적응할 수 있게 해주는 교재가 풍부합니다.
교훈 코드를 검토하는 사람이 많을수록 좋지만 이는 특정한 틀 내에서 이루어져야 합니다. 코드를 검토하는 개발자가 현재 프로세스 도입에 대한 동기를 가져야 하고 최신 보안 위협에 대한 교육을 받아야 합니다.

현재의 서비스 거부는 미래의 코드 실행 취약점이다.
Microsoft를 포함한 많은 업체들은 큰 대가를 치르고 이 교훈을 얻었습니다. 코드 문제를 발견한 엔지니어는 이 문제가 “단순한 DoS”라는 이유로 대충 넘길 수 있습니다. 보안 연구 분야는 지속적으로 진화하며, 특정 분류의 취약점에 대한 가정은 하룻밤 사이에도 변할 수 있음을 유념하십시오.
교훈 서비스 거부 문제를 간단히 넘기지 마십시오. 악의적인 사용자는 약간의 작업만으로 일부 DoS 취약점을 실제 코드 실행 취약점으로 바꿀 수 있습니다.

결론
지난 몇 년 동안 필자가 얻은 교훈이 있다면 보안 분야에서는 자신의 생각과 관점에 대해 끊임없이 의심할 준비가 되어 있어야 하며, 최신 문제에 뒤떨어지지 않도록 사전에 대책을 강구해야 한다는 점입니다. 이 기사의 교훈을 마음속에 새겨둔다면 잘 해나갈 수 있을 것입니다.

Michael Howard는 보안 프로세스 개선과 최적의 방법에 관한 업무를 중점적으로 수행하는 Microsoft의 수석 보안 프로그램 관리자로, Writing Secure Code for Windows Vista, The Security Development Lifecycle, Writing Secure Code, 19 Deadly Sins of Software Security를 포함한 여러 권의 보안 관련 서적을 공동으로 집필했습니다.