레거시 C/C++ 코드베이스에서 전면 재작성 없이도 비용과 일정을 지키며 메모리 안전을 실용적으로 달성하는 전략을 제시한다. 메모리 안전의 개념과 연속체, 새 코드의 안전화, 표적 재작성, 안전한 래핑, 규제 동향과 산업 사례(Chrome/Android, Firefox, Redis 등)를 통해 안전을 추구할 현실적인 길을 안내한다.
2025년 11월 6일
메모리 안전(버퍼 오버플로, 이중 해제 같은 약점을 배제하는 소프트웨어의 성질)은 지난 10년간 소프트웨어 커뮤니티에서 인기 주제였고, Rust 프로그래밍 언어의 부상과 함께 특히 주목을 받았다. Rust가 메모리 안전이라는 개념을 발명하거나 최초의 메모리 안전 언어였던 것은 아니지만, 그동안 메모리 안전을 달성하지 못했던 마지막 주요 영역, 즉 우리가 흔히 “시스템 프로그래밍”이라 부르는 맥락에서 댐을 무너뜨렸다.
Rust의 큰 도약은 Cyclone 같은 선행 연구(안전한 C의 부분집합으로 설계된 연구용 언어)에서 차용되고 발전된 정적 분석을 통해 컴파일 타임에 메모리 안전을 제공한 것이다. 운영체제, 데이터베이스, 파일 시스템, 임베디드 소프트웨어 등이 만들어지는 “시스템” 도메인에서 Rust가 기본적으로 메모리 안전한 경험을 제공함으로써, 정책 결정자와 엔지니어링 조직의 리더들에게 모든 도메인에서 메모리 비안전을 대대적으로 줄일 수 있다는 새로운 가능성을 제시했다.
Rust가 등장한 이후 수년 동안, 기술 기업들은 Rust를 프로덕션 시스템에 도입한 경험을 보고해 왔다. 기존 코드를 리라이트하거나, 원래라면 C 또는 C++로 작성했을 새 모듈을 Rust로 만드는 방식이다. 결과는 대체로 일관됐다. 메모리 안전 취약점이 대략 70% 감소했다는 것이다. Rust는 메모리 안전을 약속하는 데 그치지 않고, 안전 보장을 소프트웨어 보안의 실질적 개선으로 입증해 보였다. 의미론적 개선의 추상적 이점을 기업 비용의 실질적 절감으로 전환한 이 증거(취약점은 모든 이해당사자에게 비싸다)는 엔지니어링 조직을 넘어 더 넓은 조직의 관심을 끌었다.
물론, 프로그래밍 언어의 선택은 논쟁적이다. 언어는 진공 상태에서 존재하지 않으며, “일에 맞는” 언어는 강한 경로 의존성을 갖는다. 개발자들이 이미 어떤 언어를 알고 있는가? 프로젝트의 일정과 예산은? 정확성 제약은 얼마나 엄격한가? 성능 제약은? 더 많은 개발자를 채용할 예정인가, 그리고 그들을 교육할 자원은? 오픈소스 프로젝트라면 어떤 언어가 더 많은 기여자를 데려올 수 있을지 따져볼 수 있다. 어떤 프로젝트든, 필요한 다른 라이브러리나 도구와의 통합이 언어 선택을 좌우할 수 있다.
더구나 많은 프로젝트는 이미 수년—어쩌면 수십 년—전에 언어 선택을 끝냈다. 이제 무엇을 해야 할까? 오늘 가진 코드가 C나 C++로 된 메모리 비안전 코드라면, 전부 갈아엎지 않고 어떻게 안전을 추구할 수 있을까?
일부에서는 “Rust로 다시 쓰라”는 답을 내놓기도 한다. 메모리 비안전 언어로 작성된 레거시 소프트웨어를 Rust로 대체하라는 것이다. 지지자들은 이점이 명확하다고 말한다. 동급의 성능, 현대적 도구, 그리고 메모리 안전.
하지만 경험 많은 개발자들은 리라이트가 비싸고 자주 그릇된 결정임을 안다. 대규모 리라이트 요구는 대개 면밀한 트레이드오프 분석이 아니라, “못생겼다”거나 “너무 오래됐다”는 미학적 비판에서 나온다. 오히려 대규모 리라이트를 외치는 이들이야말로, 일을 잘 해내고 있는 기존 코드베이스를 이해하고 다루는 어려운 일을 해낼 능력이 부족함을 드러내는 경우가 많다.
메모리 비안전을 사업 비용으로 감수하거나, 안전을 위해 안정적인 시스템을 새 언어로 대대적으로 리라이트하는 것 사이에는 다른 길이 있다. 메모리 안전으로의 전환을 반사적으로 거부하는 것은 잘못이다. 특히 메모리 안전의 이점을 비용과 일정 면에서 효율적으로 얻을 수 있다면 더욱 그렇다.
아직 메모리 안전의 가치를 확신하지 못한다면, 이 글은 당신을 위한 것이다. 이 글의 목적은 레거시 시스템에서 메모리 안전을 추구하는 일을 그에 걸맞은 진지함과 엄밀함으로 다루는 데 있다.
메모리 안전을 추구할 가치는 충분하다. Rust가 있든 없든 마찬가지다. 시도해 보도록 설득하고 싶다.
소프트웨어 시스템은 고립되어 존재하지 않는다. 소프트웨어는 무언가를 하기 위해, 비즈니스와 개인의 필요를 충족하기 위해, 시스템을 더 효율적이거나 자동화하기 위해 만들어진다. 소프트웨어 개발은 이론적 한계가 아닌, 그것을 만드는 팀의 비용과 일정 제약에 의해 제한된다.
“메모리 안전 로드맵의 필요성”에서, “파이브 아이즈(미국, 영국, 호주, 뉴질랜드, 캐나다)” 정부 기관들은 조직들이 소프트웨어 개발을 메모리 안전 언어로 전환하기 위한 로드맵을 수립할 것을 공동 권고했다.
여기서 분명히 하자. 초점은 _로드맵_이며, 메모리 안전으로의 전환이 비용과 일정에 미치는 영향을 명시적으로 인정하고 논의한다.
예산과 일정의 제약, 그리고 효율성에 대한 열망은 애초에 소프트웨어가 만들어지는 동기다. 일단 소프트웨어가 도입되면, 그것은 종종 미션 크리티컬이 된다. 이전에 사람들이 하던 일을 그 소프트웨어가 대신하기 때문이다. 회사에는 회계사 대신 회계 _소프트웨어_가 있게 되고, 소수의 회계사가 그 소프트웨어와 상호작용해 데이터를 바탕으로 내장된 비즈니스 로직을 활용해 자신의 업무를 수행한다.
핵심 소프트웨어 시스템을 리라이트하는 것은 위험하다. 소프트웨어 자체가 그만큼 중요하기 때문이다. 구성 요소를 하나씩 교체하는 점진적 리라이트든, 특정 전환일에 일괄 교체하는 전면 리라이트든, 리라이트는 비즈니스의 정상 작동을 위태롭게 할 수 있다.
복잡하고 장기간 운영된 소프트웨어 시스템은 다른 격렬한 제약도 겪는다. 끌 수 없을 수 있다. 비즈니스에 너무 중요하고 시간 민감적이어서 유지보수나 교체를 위한 다운타임 자체가 용납되지 않을 수 있다. 또한 작성자나 이전 담당자의 전문성이 신참 개발자들에게 승계되지 않아 지식이 소실된 결과, 현재 팀이 시스템을 이해하지 못하거나 변경에 자신이 없는 잃어버린 유물 같은 시스템이 되었을 수도 있다.
소프트웨어 개발에는 지속 비용도 있다. 점진적 리라이트를 지원하기 위해서라도 그 비용을 전용해야 할 수 있다. 사업에 따라 개발팀 증원 예산이 없을 수 있으며, 리라이트에 자원을 돌리면 기능 제공이 줄어들 수 있고, 이는 용납되지 않을 수 있다.
요컨대, 리라이트(점진적 리라이트조차)는 다른 전략적 목표와의 교환으로 내려야 하는 비즈니스 결정이다. 의욕적인 개발자들은 리라이트의 상승 효과를 최선으로 주장할 수 있겠지만, 동시에 오늘 시스템 사용자에게 영향을 주는 버그를 해결하고 기능을 제공해야 하는 비즈니스의 요구와 씨름해야 한다.
동시에, 메모리 안전 언어로의 전환은 안전(따라서 보안)이라는 보통 논의에서 우선되는 명분을 넘어서는 이익도 가져올 수 있다.
널 포인터 역참조나 버퍼 경계 밖 인덱싱 같은 메모리 안전 위반은 관련 소프트웨어의 서비스 거부(고전적 CIA 삼각형의 관점에선 가용성 실패)를 초래할 수 있다. 이는 온콜 호출로 이어지는 프로덕션 장애 대응, 고객과의 SLA 미준수, 고객 이탈이나 업무 중단에 따른 매출 감소로 연결될 수 있다.
메모리 안전 이슈는 또한 공격자가 원격 코드 실행을 달성하는 킬체인의 핵심 구성요소인 경우가 많다. 1996년 “Smashing the Stack for Fun and Profit” 시절로 거슬러 올라가도, 보안 전문가들이 버퍼 오버플로 약점을 원격 코드 실행과 호스트 장악으로 전환하는 방법을 문서화했음을 볼 수 있다. 일단 그 발판을 얻으면 공격자는 데이터 유출, 네트워크 내 수평 이동, 권한 상승, 랜섬웨어를 통한 시스템 봉쇄, 봇넷 편입 등 다양한 행위를 시작할 수 있다.
소프트웨어 문제는 개발 수명주기에서 더 이른 단계일수록 고치기 싸다. 장기적으로는 버그가 아예 쓰이지 않게 막는 것이 버그바운티 대응이나 프로덕션 장애 분류보다 더 저렴하다.
이는 모든 메모리 안전 전환이 비용 대비 효과적이거나, 모든 로드맵이 최대한 공격적이어야 한다는 뜻은 아니다. 다만 메모리 안전으로의 전환에는 비용과 절감이 모두 존재함을 분명히 하려는 것이다.
메모리 안전이란 무엇인가? 대중 담론에서 메모리 안전을 밀어붙이며 당연히 있어야 할 기본 답이 있어야 하겠지만, 단 하나의 완전히 합의된 엄밀한 정의는 없다. 최근 Communications of the ACM에 발표된 글에서 표준 정의 수립을 위한 새로운 노력이 발표되었으나 이제 막 시작 단계다.
그럼에도 실무자들 사이에는 어떤 프로그램 행위가 메모리 _비안전_인지에 대한 대략적 합의가 있다. 거기서 출발하자.
내가 좋아하는 짧은 정의는 프로그래밍 언어 분야의 학자인 Michael Hicks가 제시한 것이다.
“[프로그램 실행은 특정한 나쁜 일들의 목록(이를 메모리 접근 오류라고 부름)이 결코 발생하지 않는다면 메모리 안전하다:
• 버퍼 오버플로
• 널 포인터 역참조
• Use-after-free(해제 후 사용)
• 초기화되지 않은 메모리 사용
• 불법 해제(이미 해제된 포인터 또는 malloc되지 않은 포인터의 해제)]”
이 범주들을 공간적(spatial) 메모리 안전과 시간적(temporal) 메모리 안전으로 더 세분하기도 한다. 공간적 안전은 프로그램이 접근해서는 안 될 메모리 위치에 접근하는 문제(예: 버퍼 오버플로)를 다루고, 시간적 안전은 메모리 연산의 순서 오류—예컨대 초기화 전에 읽기, 이미 해제된 포인터를 해제하기, 해제 후 포인터 사용—를 다룬다.
또한 메모리 안전 이슈를 다루는 CWE(Common Weakness Enumeration) 범주가 있으며, 이는 Hicks의 목록을 더 세분화한다. CWE는 소프트웨어 약점의 분류 체계로, CWE 표현에 따르면 “특정 상황에서 취약점 도입에 기여할 수 있는 소프트웨어의 상태”이다.
CWE의 메모리 안전 범주에서는 “버퍼 오버플로”가 여섯 가지 구체적 약점으로 더 쪼개지며, 그중 일부는 다시 변형으로 분해된다. 최대한의 정밀함이 필요할 때 유용하지만, 이 글의 목적에는 다소 과할 수 있다.
이 정의들은 메모리 _비안전_이 무엇인지 꽤 분명한 그림을 제공한다. 그러므로 메모리 안전이란 프로그램에 그 약점들이 없음을 보장하는 상태다. 이는 프로그램 의미론에 대한 컴파일 타임 제약이나, 가비지 컬렉터에 의한 런타임 메모리 관리로 달성될 수 있으며, 보장이 유지되는 한 방식은 중요하지 않다.
이 대목에서 통찰력 있는 관찰자는 문제 제기를 할 것이다. Rust는 비안전을 허용한다! 아예 unsafe 키워드가 있지 않은가! 그게 C나 C++의 보장과 뭐가 다른가?
정답이다. Rust는 프로그래머가 unsafe 코드를 작성하는 것을 허용한다. 그러나 안전이나 보안에 종사하는 이들이라면 누구나 알듯, 디폴트는 중요하다. 사실, 디폴트는 매우 중요하다!
안전벨트를 예로 들어보자. 안전벨트는 1980년대 후반부터 1990년대 초반 사이 미국 전역에서 의무화되었다. 1985년, 주 단위 의무화가 시작될 당시 안전벨트 착용률은 21%였다. 1994년에는 평균 58%. 2017년에는 89.7%였다. 디폴트의 변화가 착용률을 크게 끌어올렸고, 더 많은 생명을 구했다. 미 교통안전국(NHTSA)은 2017년 한 해에만 약 1만5천 명의 생명이 안전벨트로 구해졌다고 추정한다.
소프트웨어에도 같은 진리가 적용된다. 4.0.0(2017년 공개) 이전 버전의 인기 키-값 저장소 Redis는 기본 설정에서 접근 제어를 제공하지 않았다. 새 사용자가 무심코 인스턴스를 공개적으로 노출하는 경우가 잦았고, 이는 데이터 유출이나 호스트 침해 벡터로 이어졌다. 4.0.0부터 Redis는 기본 설정과 비밀번호 없이 실행될 때 “보호 모드”로 진입해 루프백 인터페이스로 접근을 제한한다. Redis 회사 자체가 자랑했듯, 보호 모드 도입 이후, 인기 호스트 수집기 Shodan.io가 추적한 공개 접근 가능한 Redis 인스턴스 수는 크게 줄었다. 2017년에는 약 17,000개로 파악되었으나, 2020년 보안업체 트렌드마이크로의 감사에서는 8,000개로 감소했다.
메모리 안전으로 돌아가서, 언어의 메모리 안전 보장은 연속체로 볼 수 있으며, 언어를 “기본적으로 메모리 안전”과 “기본적으로 메모리 비안전” 그룹으로 나눌 수 있다. 이는 OpenSSF(오픈소스 보안 재단) 메모리 안전 SIG가 권고한 프레이밍이며, 선택지를 명확하게 해 준다.
• 기본적으로 메모리 안전한 언어 사용
• 기본적으로 메모리 안전한 언어를 사용해 기본적으로 메모리 비안전한 언어와 인터페이스하기
• 기본적으로 메모리 비안전한 언어 사용
여기서 기본적으로 메모리 안전한 언어에는 Rust뿐 아니라 Java, C#, Go, Swift, Python, Ruby 등 일반적인 가비지 컬렉션 언어가 포함된다. 기본적으로 메모리 비안전한 언어에는 C와 C++이 대표적이며, 아마 멀찍이서 논의를 지켜본 이들에게 놀라울 수 있지만 Zig도 포함된다.
Zig는 프로그래머가 스스로 메모리 안전한 프로그램을 더 편하게 작성하도록 도와주지만, 가장 보수적인 설정에서도 메모리 안전을 보장하지 않으므로 메모리 안전 언어가 아니다. Jamie Brandon의 Zig 메모리 안전 분석은 Zig의 보장이 왜 불충분한지 잘 설명한다.
이제 메모리 안전과 메모리 안전 언어에 대한 공감대를 바탕으로, 현실 세계 프로그램에서 메모리 안전을 추구하는 구체 전략을 살펴보자.
이하 전략은 메모리 안전의 이익을 극대화하고 이를 추구하는 비용을 최소화하는 것을 목표로 한다. 어떤 접근이 옳은지는 맥락에 따라 달라지며, 구성요소의 중요도, 현재 및 목표 언어, 팀, 일정 등을 고려해 결정해야 한다.
첫 번째이자 가장 분명한 선택은 새 코드를 메모리 안전하게 만드는 것이다. 즉, 새 구성요소를 메모리 안전 언어로 작성하는 것이다. 간단해 보이지만, 이 접근을 성공시키려면 몇 가지 주의할 점이 있다.
우선, 메모리 안전 코드와 새 메모리 비안전 코드를 나란히 도입하면 메모리 안전의 이점을 누리기 어렵다. 이렇게 생각해 보자. 테스트, 코드 리뷰, 버그바운티 등으로 계속 보증하는 고정된 코드베이스에서 취약점의 밀도는 시간이 지남에 따라 기하급수적으로 감소한다. 코드베이스에서 취약점 밀도가 낮아질수록 새 취약점 발견 속도도 감소하고, 전체 보증 수준은 _증가_한다. 코드베이스에 가장 위험한 일은 변경이다. 메모리 비안전 언어의 경우, 변경은 메모리 안전 취약점을 유발할 수 있다.
Google Chrome과 Android 팀은 코드베이스에서 메모리 안전 언어로의 전환을 장려한 경험을 광범위하게 공개했다. 그들은 모든 새 코드는 샌드박스에서 실행하거나 메모리 안전 언어로 작성해야 한다는 “Rule of Two”를 도입했다. 실무적으로는 샌드박싱이 어렵기 때문에, 대부분의 경우 개발자들은 자연스레 메모리 안전을 추구하게 되었다.
놀랍게도, 이 정책의 혜택은 리라이트하지 않은 코드 영역까지 코드베이스 전반으로 퍼졌다. 새 코드가 갖는 안전 메커니즘 덕분에 일정 수준의 보증이 주어지므로, 팀은 보증 노력을 이제 정적인 구(舊) 코드에 집중할 수 있었다. 이를 통해 코드베이스의 메모리 안전 취약점 전체 발생률을 낮췄을 뿐 아니라, 취약점 전반의 발생률도 낮출 수 있었다.
때로는 메모리 안전 언어로 코드를 재작성하는 것이 옳을 수 있다. 하지만 이는 대개 현재의 메모리 비안전 코드가 직면한 문제를 충분히 이해한 다음에야 추구할 길이다.
Rust 개발 초기, Mozilla(파이어폭스 브라우저 제작사)의 지원을 받았고, Rust 자체 컴파일러를 제외하면 대표 프로젝트는 Servo 웹 렌더링 엔진이었다. 그럼에도 Mozilla가 Firefox에 처음 통합한 Rust 코드는 Servo가 아니었다. MP4 비디오 파일 파서였다. 오랫동안 취약점의 근원이었던 기존 C++ 파서를 Rust로 교체한 것이다. Firefox는 신뢰할 수 없는 출처의 MP4 파일을 파싱해야 하며, 파싱 실패는 치명적일 수 있다. Mozilla에게 이는 작지만 보안에 결정적인 표면적이었고, 재작성 대상으로 삼기에 적절했다.
타기팅에 도움이 되는 또 다른 도구로 Kelly Shortridge의 SUX 규칙이 있다. Sandbox free(샌드박스 없음), Unsafe(비안전), eXogenous(외생—신뢰할 수 없는 외부 입력)한 코드를 겨냥하라는 것이다. 신뢰할 수 없는 입력을 처리하고, 샌드박스 없이 실행되며, 메모리 비안전 언어로 작성된 코드를 우선 재작성 대상으로 삼아라. 코드베이스에서 이런 영역을 찾으면, 메모리 안전 취약점이 있을 때 악용 위험이 높은 경로를 빠르게 식별할 수 있다.
기존 메모리 비안전 코드를 메모리 안전 언어로 완전히 재작성하는 것이 현실적이지 않다면, 메모리 안전 인터페이스로 감싸는 것이 타당할 수 있다. 이 경우, 메모리 비안전 언어로 된 원 코드와 인터페이스의 정확성에 대한 안전 보장은 여전히 프로그래머의 몫이다. 그러나 그 위에 안전하고 신뢰할 수 있는 새 코드를 구축할 수 있게 된다. 퍼저 테스트, sanitizers에 의한 분석, 형식 모델링 같은 기법으로 원 코드를 계속 보증한다면, 래핑된 잠재적 비안전 코드에 대한 신뢰를 점차 높일 수 있다.
실제로 Rust 표준 라이브러리의 일반 컨테이너 타입들이 바로 이렇게 작성되어 있다. 내부에서는 버퍼와 포인터를 가능한 한 효율적으로 관리하기 위해 unsafe 코드를 사용하지만, 사용자에게 제공하는 인터페이스는 버퍼, 포인터, 길이 같은 자료에 접근할 수 없게 해 메모리 안전 보장을 위반할 여지를 주지 않는다.
이 “래핑” 접근은 현실적으로 제거하거나 교체할 수 없는 메모리 비안전 코드의 “폭발 반경”을 제한하고, 그 코드에 대한 감사를 위한 범위와 보증 비용도 제한한다.
메모리 안전 논의에서 가장 강경한 회의론자들이 흔히 내놓는 반응이 있다. 프로그래머가 그냥 더 좋은 코드를 쓰면 된다는 것이다. 메모리 안전의 가드레일로부터 이득을 보는 프로그래머는 _나쁜 프로그래머_이며, _진짜 프로그래머_는 기계가 자신의 작업을 이중 확인해 줄 필요가 없을 만큼 충분히 숙련되어 있다고 노골적 혹은 암묵적으로 주장한다.
분명히 하자. 이는 진지한 기술적 논증으로 포장된 마초적 자기과시—반지성적 헛소리다. 진지하게 받아들일 필요가 없으며, 이런 주장을 펴는 사람은 근본적으로 비진지하다고 보고 무시하는 편이 낫다.
인류 성취의 역사에서 질적 도약은 사람들이 어느 날 갑자기 일어나 “일을 더 잘하기로” 결심해서 일어난 적이 없다. 생산성이나 품질 개선, 오류와 피해 감소는 새로운 기법, 프로세스, 도구의 발명 때문에 일어난다.
1980~90년대 교통사고 사망자 감소는 운전자들이 갑자기 운전을 잘하게 되었기 때문이 아니라, 각 주가 안전벨트 의무화를 시행했기 때문이다.
개인이 더 숙련되어 빨리 일하거나 오류를 줄일 _수_는 있다. 하지만 _대규모 집단_은 어떤 변화의 유인이나 촉진이 없이는 일반적으로 그렇게 되지 않는다. 비기술적 개선이라도 프로세스 개선이나 행동에 대한 인센티브에서 나온다. 최근 수십 년 동안 병원에서의 오류가 줄어든 것은 표준 체크리스트 사용 확대와 응급 상황에 필요한 공통 물품을 담은 크래시 카트의 보급 때문이다.
메모리 안전에 반대하며 집단적 자기계발을 주장하는 프로그래머들은 실현 불가능한 미래를 내세워, 소프트웨어 안전과 보안을 개선할 신뢰할 수 있는 기회를 대체하려 한다. 특정 상황에서 메모리 안전으로 가는 개별 경로에 대해 신뢰할 만한 반론은 있을 수 있다. 하지만 업계 전반의 갑작스러운 실력과 품질의 향상은 그 반론에 포함되지 않는다. 이를 분명히 해 두는 것이 중요하다.
메모리 비안전 언어 사용이 일반적으로 용인되지 않게 될지—공식 정부 규제나 소프트웨어 구매 요건의 강화로 인해—는 논의의 유령처럼 따라다닌다.
오늘날 미국 안팎 어느 기관도 기본적으로 메모리 비안전한 언어의 사용을 금지하지 않는다. 또한 정부 조달에서 기본적으로 메모리 안전한 언어의 사용이나, 심지어 메모리 안전 로드맵의 존재를 요구하는 구매 요건도 없다.
앞서 언급한 파이브 아이즈의 “메모리 안전 로드맵의 필요성”은 조직이 메모리 안전 추구를 위한 로드맵을 수립할 것을 _권고_하지만, 이는 규제가 아니며, 미국이나 다른 곳의 연방 소프트웨어 조달 정책에 그런 로드맵을 요구하도록 한 개정은 없다. 미국은 C나 C++을 금지하지 않는다. 이들 기관은 향후 소프트웨어 개발에서 이들 언어를 멀리할 것을 권고했지만, 기존 코드를 무차별적으로 대규모 재작성하라고 권고하지 않았다.
또한 규제나 요구사항을 수립하는 절차는 도전에 부딪힐 것이며, 성사되든 아니든 발효되기까지 시간이 오래 걸릴 것이고, 그 과정에서 충분한 피드백과 검토 기회가 있을 것이다.
첫째, 미국에서 메모리 안전 관련 규제를 추진하려면, 관련 관할권을 확립할 수 있는 적절한 기관이 나서야 한다. 또한 미국 대법원이 2024년 Loper Bright Enterprises v. Raimondo 판결에서 Chevron 판례상 행정기관에 대한 사법부의 존중을 폐기했기 때문에, 메모리 안전 규제를 추진하려면 의회가 명시적으로 위임해 법원의 기관 규칙 제정을 뒤집을 여지를 줄여야 할 가능성이 크다.
둘째, 조달 요구사항 측면에서(정부의 구매 규칙), FAR(Federal Acquisition Regulation, 연방조달규정)을 개정해 메모리 안전 요구를 포함시켜야 한다. 참고로 2020년 바이든 대통령은 연방 정부가 구매하는 모든 소프트웨어에 SBOM(소프트웨어 자재명세서) 포함을 요구하도록 FAR 개정을 요청하는 행정명령 14028을 서명했다. 현재까지 해당 변경은 이뤄지지 않았고, FAR에는 그런 요구사항이 없다.
이는 규제나 향후 연방 구매 요구사항이 불가능하다는 뜻이 아니라, 단지 오늘날 그런 조치가 없고, 설사 변화가 있다 해도 제정과 실행까지 시간이 걸릴 것이라는 점을 지적하는 것이다.
미국 정부의 역할은 지금까지 메모리 안전의 응원자이자 촉진자였다. 국가사이버국(ONCD)의 “미래 소프트웨어는 메모리 안전해야 한다” 보고서, CISA(사이버보안·인프라안보국) 등과 함께한 “메모리 안전 로드맵의 필요성,” 그리고 업계와 협력해 소프트웨어 보안을 개선하는 Secure by Design 이니셔티브에 메모리 안전 권고를 포함한 것이 그 예다.
정부의 강제 없이도, 기술 업계의 많은 조직이 메모리 안전 추구에 공개적으로 동의하고 있다. 2023년 국가사이버국은 오픈소스 소프트웨어 보안 강화를 어떻게 지원할지에 대한 대중의 의견을 구하는 RFI(정보요청)를 냈다. 이 RFI에는 오픈소스에서 메모리 안전 언어 채택을 촉진하는 방안에 대한 관심이 포함되었다.
대학, 싱크탱크, 기업, 개인 등 응답자들은 압도적으로 메모리 안전으로의 전환을 지지했다. 기존 코드 전부를 비안전 언어에서 고쳐 쓰자는 강경한 목표를 내세운 이는 거의 없었지만, 새 코드에서 메모리 안전을 추구하거나, 가능할 때 보안 민감 맥락에서 핵심 구성요소를 재작성하는 가치를 인정하는 응답은 많았다.
일부 기업, 특히 Google은 메모리 안전의 가치에 대한 경험을 특히 적극적으로 공유하고 있다. 이들에게 메모리 안전의 약속은 Google Chrome 브라우저나 Android 운영체제처럼 장수 제품의 보안 관련 비용을 줄이는 것이다. 메모리 안전 취약점을 원천에서 줄이면, 소프트웨어 개발 수명주기에서 취약점 비용을 왼쪽으로 이동시킬 수 있다. 개발 중에 버그를 잡아 출하 자체를 막는 비용은, 보안 제보를 받고 버그바운티를 지급할지 모르는 가운데 패치를 조율·준비·배포하는 비용보다 몇 배나 싸다.
일부에서는 미국 정부 등의 메모리 안전 권고가 C나 C++의 강제적인 종말을 예고한다고 두려워한다. C++의 창시자이자 C++ 규격을 유지하는 ISO WG의 핵심 구성원인 Bjarne Stroustrup은 C++가 메모리 안전 요구에 부응하지 못해 직면한 실존적 위협에 대해, 최근 논문과 연설에서 경종을 울리고 있다. 기본적으로 메모리 비안전한 언어로 작성된 소프트웨어가 미래에 금지되거나 사실상 시장에 내놓기 어려워질지 모른다는 암시가 분명하다.
이 두려움은 과장되었으면서 동시에 옳다. 미국이나 다른 어떤 정부도 C나 C++을 금지하는 데 근접했다고 보긴 어렵다. 하지만, 대규모 사례 연구가 쌓일수록 메모리 안전의 이점이 더 분명해지고 있으며, 자연스러운 인센티브가 기본적으로 메모리 안전한 언어로의 사용과 개발자 관심을 서서히 키워갈 것이라는 점은 정확하다. C와 C++은 죽지 않을 것이다. 그러나 아마도 Cobol이나 Ada처럼 레거시 언어로 쇠퇴할 것이다. 여전히 일정 수준의 관심과 커뮤니티를 유지하겠지만, 이 언어들로 커리어를 이어갈 개발자는 줄어들 것이고, 안전 결함을 해결하는 대대적 변화 없이는 인기도와 사용량이 다시 상승하기는 어려울 것이다.
메모리 안전 언어는 오늘날 소프트웨어 보안을 대폭 개선할 가장 명확한 기회다. 메모리 안전이 모든 소프트웨어 약점을 없애지는 못하더라도, 불균형적으로 심각한 취약점으로 이어지는 특히 성가신 범주를 제거한다. 이들 취약을 다루는 다른 기법(예: CHERI 같은 하드웨어 기반 접근)도 있지만, 성숙도가 낮고 대규모 도입이 더 어렵다.
오늘날 메모리 안전의 가능성은 안전벨트 의무화가 광범위하게 채택되기 직전 자동차 안전의 상태와 비슷하다. 자동차 제조사가 전 차종에 안전벨트를 기본 탑재하고, 주들이 운전자 안전벨트 착용을 요구하기 시작하자, 교통사고 사망률과 부상 심각도가 급감했다. 안전벨트가 자동차 안전 문제를 해결하진 못했지만, 신뢰할 만하게 개선했고 비용도 놀라울 정도로 낮았다.
메모리 안전도 마찬가지다. 심각한 범주의 취약점을 대대적으로 줄이면서, 장기적으로 소프트웨어 개발과 운영 비용을 절감할 기회가 있다. 메모리 안전은 만능 해결책은 아니지만, 업계가 공격적으로 추구해야 할 신뢰할 수 있고 비용 효율적인 보증 기법이다. 규제가 따라올 때까지 기다릴 필요가 없다. 지금 행동하는 것이 우리의 이익이다.
Steve Klabnik(Oxide Computer Company 엔지니어, Rust 코어 팀 전 구성원), Michael Chernicoff(MITRE 선임 소프트웨어 엔지니어)께서 출간 전 이 글을 검토하고 피드백을 주셨습니다. 감사드립니다.
Andrew Lilley Brinker는 MITRE의 수석 엔지니어로 소프트웨어 보안을 담당한다. CVE 품질 워킹그룹에 기여하고, OmniBOR 코어 팀에서 활동하며, Hipcheck 개발을 이끈다. 남부 캘리포니아에 아내, 두 마리의 개와 함께 산다.
Copyright © 2025 held by author. Publication rights licensed to ACM.
대외 공개 승인; 배포 무제한. 대외 공개 케이스 번호 25–1514. MITRE 소속 표기는 신원 확인을 위한 것이며, 본문에 담긴 저자의 입장, 의견, 시각에 대해 MITRE가 동의하거나 지지함을 암시하려는 의도가 아닙니다.

Queue 제23권 4호에 최초 게재
이 글에 대한 의견은 ACM 디지털 도서관에 남겨주세요.
더 읽을거리:
Louis Dionne, Alex Rebert, Max Shavrick, Konstantin Varlamov - Practical Security in Production
프로덕션에서 기존 C++ 코드의 광대한 지형에서 메모리 안전을 개선하는 과제는 실용적 해법을 요구한다. 표준 라이브러리 하드닝은 거의 모든 C++ 개발자가 사용하는 기초 구성요소의 공간적 안전 취약점의 흔한 근원을 직접 겨냥하는 강력하고 실용적인 접근이다. Apple과 Google에서의 우리의 경험은 프로덕션 환경에서 놀라울 만큼 미미한 성능 오버헤드로도 상당한 안전 이득을 달성할 수 있음을 보여준다. 이는 신중한 라이브러리 설계, 현대 컴파일러 기술, 프로파일 유도 최적화의 결합 덕분이다.
Christoph Kern - Safe Coding
세이프 코딩은 크고 복잡한 시스템의 안전을 구축하고 추론하는 모듈식·합성적 접근을 구현한다. 추상화의 안전성에 대한 어렵고 미묘한 추론은 그 구현부로 국소화된다. 추상화 내부의 위험한 연산의 안전은 오직 그 추상화의 API와 타입 시그니처로 뒷받침되는 가정에만 의존해야 한다. 반대로, 안전한 추상화와 안전한 코드의 합성은 구현 언어의 타입 체커가 자동으로 검증한다. 형식 기법 자체는 아니지만, 세이프 코딩은 엄격한 형식 검증의 원리와 기법에 뿌리를 둔다.
Jinnan Guo, Peter Pietzuch, Andrew Paverd, Kapil Vaswani - Trustworthy AI using Confidential Federated Learning
현대 AI 규제의 초석은 보안, 프라이버시, 책임성, 투명성, 공정성이다. 고전적 FL은 투명성과 책임성의 대가로 보안과 프라이버시에 중점을 두어 설계되었다. CFL은 FL을 TEE와 커밋먼트와 신중히 결합해 이 격차를 해소한다. 또한 CFL은 코드 기반 접근제어, 모델 기밀성, 추론 중 모델 보호 등 바람직한 보안 속성을 제공한다. 기밀 컨테이너, 기밀 GPU 등 기밀 컴퓨팅의 최근 발전은 기존 FL 프레임워크가 낮은 오버헤드로 CFL을 지원하도록 원활히 확장될 수 있음을 의미한다.
Raluca Ada Popa - Confidential Computing or Cryptographic Computing?
MPC/동형암호에 의한 안전 계산과 하드웨어 엔클레이브 접근은 배포, 보안, 성능에서 상호 교환이 있다. 성능 측면에서는 어떤 워크로드를 염두에 두느냐가 매우 중요하다. 단순 합, 저차 다항식, 단순 ML 같은 간단한 워크로드에서는 두 접근 모두 실전 사용이 가능하지만, 복잡한 SQL 분석이나 대규모 ML 모델 학습 같은 풍부한 계산에서는 현시점에서 많은 실제 배포 시나리오에 충분히 실용적인 것은 하드웨어 엔클레이브 접근뿐이다.
© ACM, Inc. All Rights Reserved.