보안 부채 또는 버그가 발생했을 때
때때로 IT 업계는 일시적인 유행이거나 중대한 이슈로 떠오르는 새로운 우려에 사로잡힐 때가 있습니다. 최근에는 '보안 부채'라는 용어가 IT 뉴스 플랫폼에서 자주 등장하고 있습니다. 이 글에서는 보안 부채의 본질과 그 의미를 살펴보고자 합니다.
기술 부채에서 보안 부채로
"기술 부채"라는 개념은 많은 사람들에게 친숙한 개념으로, 프로젝트가 관리 가능한 비율을 넘어 확장되면서 발생하는 문제를 의미합니다. 이 '규모'는 코드 줄, 모듈, 함수 또는 기타 메트릭으로 측정할 수 있으며, 새로운 기능을 추가하는 동시에 기존 코드를 유지 관리하는 팀의 역량을 반영합니다.
예를 들어, 개발이 막 시작된 애플리케이션에 새로운 기능을 추가하는 것은 동일한 애플리케이션에 새로운 기능을 추가하는 것보다 훨씬 더 어렵습니다. 움직이는 부분이 적고 코드의 여러 부분 간의 상호 작용이 적기 때문에 새로운 기능을 추가해도 기존 기능이 손상될 가능성이 적습니다. 애플리케이션이 발전함에 따라 모든 변경 사항이 코드의 다른 곳에서 예상치 못한 상호 작용을 일으킬 수 있습니다. 이는 devspeak에서 "버그를 추가했습니다"라는 의미일 뿐입니다. 제한된 시간과 리소스에 직면한 개발자는 새로운 개발과 버그 수정을 병행해야 하므로 전체적인 진행 속도가 느려집니다. 이러한 유지 관리 백로그는 "기술 부채"를 구성합니다.
이러한 버그 중 일부는 전부는 아니더라도 코드에 충분히 오래 방치되면 보안 문제로 전환될 수 있습니다.. 예를 들어, 어딘가에 오버플로 또는 언더플로 변수가 있으면 단순히 잘못된 값을 보고하거나 누군가 이를 트리거하는 방법을 찾으면 애플리케이션의 관련 없는 부분에서 메모리 손상을 일으킬 수 있습니다. 이것이 바로 '보안 부채', 즉 누군가가 문제를 해결할 때까지 수개월 또는 수년 동안 코드에 존재하는 보안 버그입니다. 이러한 취약점을 방치하면 수정되기 전에 악용될 수 있습니다.
그렇다면 왜 다시 돌아오는 것일까요?
가장 큰 원인은 복잡성입니다. 코드베이스는 점점 더 커지고 있습니다.. 소프트웨어에는 항상 새로운 기능이 추가되는 것이지 그 반대의 경우는 없습니다. 즉, 더 많은 코드가 추가되는 것이지 제거되는 것이 아닙니다. 인간의 두뇌는 디지털 창작물의 복잡성을 완전히 이해하는 데 어려움을 겪고 있습니다.
리눅스 커널 코드 베이스를 생각해 보세요. 2001년에 240만 줄이었던 코드가 2015년에는 2,000만 줄 이상으로 증가했습니다.. 누구도, 아니 어떤 팀도 그 모든 측면을 적절히 파악할 수 없습니다. 따라서 누군가 새로운 코드 줄을 추가할 때마다 정상적으로 작동할 수도 있고 다른 곳에서 멜트다운을 일으킬 수도 있습니다. 동전을 던지면 동등한 기회가 주어집니다.
이는 커널이나 이 정도 규모의 프로젝트, 심지어 오픈 소스 프로젝트에만 국한된 문제가 아닙니다. 이러한 복잡성 증가는 비공개 소스 독점 소프트웨어에서도 동일하게 발생하며, 단지 이를 보여줄 수 있는 코드 크기 메트릭이 없을 뿐입니다. 비교를 위해 바이너리 크기를 살펴보면, Windows 95는 13개의 플로피 디스크에 1.68MB(오타가 아니라, 해당 디스크는 는 더 많은 데이터를 담기 위해 다른 트랙 레이아웃을 사용했으며, 복사 방지 메커니즘의 이중 용도로 사용되었습니다.). Windows 11은 약 5GB의 ISO로 제공됩니다.
따라서 코드 베이스가 늘어난 것은 맞습니다.
또한 개발자의 실력이 갑자기 나빠진 것도 아닙니다. 일반적인 개발자는 수십 줄의 코드는 기억을 통해 정확하게 이해할 수 있습니다. 좋은 개발자는 그 두 배 또는 세 배 정도입니다(일부러 모호하게 표현한 것입니다. 측정하기 어렵기 때문에). 모두에게 며칠 또는 몇 주 동안 보지 못했던 코드를 보는 것은 외국어를 처음 읽는 것과 같습니다.를 읽는 것과 같으며 컨텍스트 전환에는 시간이 걸립니다.
프로젝트 전체를 이해하는 것은 더 이상 기대할 수 있는 일이 아닙니다. 우리가 버그를 코딩한다는 사실은 이 사실을 극명하게 보여줍니다.
그게 다인가요?
라이브러리나 타사 컴포넌트가 추가될 때마다 '숨겨진 복잡성'으로 인해 문제가 더욱 복잡해집니다. 최근 보고서에 따르면 평균 Java 프로젝트에는 약 150개의 종속성전년 대비 크게 증가한 것으로 나타났습니다. 이러한 복잡성은 이미 어려운 퍼스트 파티 코드 관리 작업을 더욱 어렵게 만듭니다.
보안 부채 해결
이 모든 코드에는 본질적으로 버그가 포함되어 있으며, 그 중 상당수는 보안 문제와 직결됩니다. 이러한 버그를 적시에 올바르게 처리하는 것은 어려운 일입니다. 얼마나 어려운지는 여러 가지 요인에 따라 달라집니다:
- 얼마나 빨리 탐지되는지는 개발 및 빌드 파이프라인에서 발생하는 테스트에 따라 달라집니다: 여러 개발자가 장기간에 걸쳐 코드를 커밋하는 긴 병합 기간의 마지막에 보안 검사가 발생하는 경우, 알림이 트리거되면 원래 개발자는 더 이상 어떤 문제가 구현된 이유를 기억할 수 없기 때문에 문제 해결에 훨씬 더 많은 노력을 기울여야 합니다.
- 테스트가 얼마나 포괄적인지: 특정 문제만 테스트하고 있나요? 정적 분석은 잘못 입력된 변수나 버퍼 오버플로, NULL 사용과 같은 특정 패턴만 찾고 있을 수도 있습니다. 다른 문제는 발견될 때까지 눈에 띄지 않을 수 있습니다.
- 확인된 전체 문제 수: 해결해야 할 보안 문제가 많이 쌓여 있는 경우 이를 모두 해결할 수 있는 시간, 노하우, 인력 등의 리소스를 확보하고 있나요? 우선순위를 정하고 있나요? 다른 곳에서 우선순위가 낮은 문제가 갑자기 더 중요해지는 일이 발생하면 어떻게 하나요? 시스템이 이에 대응할 수 있을 만큼 유연하게 대응하고 있나요?
보안 부채에는 여러 가지 측면이 있지만 이 글에서는 몇 가지 핵심적인 문제만 살펴봅니다. 이 글의 목표는 개발자나 팀이 적절하게 관리할 수 있는 능력을 넘어 복잡성이 커질 때 기술 부채가 보안 부채로 전환되는 문제에 대해 경종을 울리는 것이었습니다.
보안 테스트 개선, 조기 보안 테스트, 코드 커밋 전 보안 테스트(모든 사람이 커밋한 후에만 확인하는 것이 아니라), 동료 검토 등 이 문제를 해결할 때 사용할 수 있는 몇 가지 전술이 있습니다, 제삼자에게 라이브러리 검사 아웃소싱또는 코드 베이스가 증가함에 따라 더 많은 개발자를 고용할 수도 있습니다. 이러한 제안 중 어느 하나만으로는 문제를 완전히 해결할 수는 없지만, 함께 사용하면 복잡성을 조금 더 오래 억제하고 그 영향을 완화할 수 있습니다.
참고: 이 문제에 대해 자세히 알고 싶으시다면 팟캐스트 '엔터프라이즈 리눅스 보안'의 84번 에피소드에서 해당 주제를 다루고 있습니다. 모든 팟캐스트 플랫폼 또는 다음에서 찾을 수 있습니다. 실시간 녹음 세션이 있는 YouTube.