실패할 수 없었던 보안 점검
요약
AI 에이전트 실습 환경을 구축하던 중, 보안 설정 검증 스크립트가 잘못된 식별자 사용으로 인해 보안 취약점을 발견하지 못하고 '정상'으로 오판한 사례를 다룹니다. 설정 이름의 불일치가 어떻게 치명적인 보안 허점으로 이어지는지 설명합니다.
핵심 포인트
- 설정 명령과 검증 도구 간의 식별자(Name) 불일치 주의
- 시스템의 '응답 없음'을 '정상'으로 간주하는 로직의 위험성
- 검증 스크립트 자체가 보안 허점이 될 수 있음을 인지
- 사소한 서식 오류가 심각한 보안 버그의 전조일 수 있음
내 스크립트는 초록색 [OK]를 출력했습니다. 점검 중이던 설정은 올바른 상태였습니다. 이 두 가지 모두 사실이었지만, 둘 다 중요하지 않았습니다. 왜냐하면 [OK]를 출력한 그 점검은 그 외의 다른 것은 출력할 수 없도록 설계되어 있었기 때문입니다.
이 일이 어떻게 일어났는지 설명하고자 합니다. 제가 직접 작성한 코드이기도 하고, 이것이 보안 도구들이 실패하는 가장 흔한 방식이라고 생각하기 때문입니다.
내가 만들고 있었던 것
저는 사이버 보안 (Cybersecurity) 학생이며, 이번 달 NVIDIA가 출시한 AI 에이전트 프레임워크 (AI agent framework)를 연구하기 위해 실습 환경 (Lab)을 구축하고 있었습니다. 이 프레임워크는 언어 모델 (Language model)이 작성한 코드를 실행할 수 있습니다. NVIDIA의 자체 문서에서는 그 의미를 매우 직설적으로 설명합니다. 생성된 코드가 파일을 삭제하거나, 개인 데이터를 가야 할 곳이 아닌 다른 곳으로 전송하거나, 실행되는 환경을 수정할 수도 있다는 것입니다. 그들은 실제 파일로부터 격리된 가상 머신 (Virtual machine) 내부에서 이를 실행하라고 권고합니다.
그래서 저는 가상 머신을 구축했습니다. 공유 폴더도 없고, 가상 머신과 내 컴퓨터 사이의 클립보드 공유 (Clipboard sharing)도 없으며, 드래그 앤 드롭 (Drag and drop)도 불가능한 가상 머신입니다. 샌드박스 (Sandbox)와 실제 하드 드라이브 사이의 모든 채널을 차단했습니다.
그다음 제가 자랑스럽게 생각했던 작업을 수행했습니다. 모든 항목을 제대로 체크했다는 사실을 단순히 믿는 대신, 머신의 설정을 다시 읽어와 각 항목을 확인하는 스크립트를 작성했습니다. 제어 항목을 설정한 다음, 그 제어가 실제로 적용되었는지 검증하는 것입니다. 이 둘은 서로 다른 것이며, 두 번째 단계를 건너뛰는 것이 사람들이 서류상으로만 보호받게 되는 이유입니다.
그것은 올바른 본능이었습니다. 하지만 제 구현 방식은 잘못되었습니다.
버그
점검 항목은 클립보드 (Clipboard)가 비활성화되었는지 물었습니다. 하지만 설정에 잘못된 이름을 사용했기 때문에 아무런 답변도 받지 못했습니다. 그리고 시스템은 '답변 없음'을 '예(Yes)'로 처리했습니다.
이것이 전부입니다. 이보다 더 정교한 것은 없습니다.
제가 질의(Querying)하던 도구는 클립보드 설정을 하나의 이름으로 보고합니다. 하지만 처음에 설정을 구성하기 위해 사용했던 명령은 동일한 것에 대해 다른 이름을 사용했습니다. 저는 두 이름이 일치할 것이라고 가정했습니다. 하지만 일치하지 않았습니다. 그래서 제 점검은 (시스템이 판단하기에) 존재하지 않는 설정을 검색했고, 아무것도 찾지 못하자 모든 것이 정상이라고 결론지었습니다.
만약 제가 클립보드 (clipboard)를 완전히 열어둔 상태로 두었더라도, 점검은 정확히 똑같은 초록색 [OK]를 출력했을 것입니다.
어떻게 찾아냈는가
보안 점검을 테스트해서 찾은 것은 아닙니다. 이 점에 대해서는 솔직해지고 싶습니다. 왜냐하면 실제 답이 깔끔하게 꾸며낸 이야기보다 더 교훈적이기 때문입니다.
동일한 스크립트가 마지막에 순전히 제가 읽을 수 있도록 머신의 구성 (configuration) 요약본을 출력했습니다. 저는 그 요약본이 짧다는 것을 알아차렸습니다. 제가 보길 기대했던 몇 가지 설정들이 목록에 없었습니다. 평소라면 그냥 무시하고 넘어갔을 법한 서식 오류 (formatting glitch)처럼 보였습니다.
하지만 저는 그것을 추적했고, 그 설정들이 요약본에서 누락된 이유는 보안 점검이 제대로 작동하지 않았던 이유와 동일하다는 사실이 밝혀졌습니다. 바로 제가 이름을 잘못 입력했기 때문입니다. 미적인 버그 (cosmetic bug)와 보안 버그 (security bug)는 하나의 공통된 원인을 공유하고 있었습니다. 무해한 버그는 눈에 보였습니다. 위험한 버그는 설계상 눈에 보이지 않았습니다. 실패할 수 없는 점검은 통과한 점검과 똑같이 보이기 때문입니다.
저는 운이 좋았습니다. 엄격함 (rigor)을 통해 찾아냈다고 말하고 싶지만, 사실은 관련 없는 무언가가 약간 이상해 보였을 때 그것을 무시하지 않았기 때문에 찾을 수 있었습니다.
수정 사항, 그리고 더 중요했던 부분
이름을 수정하는 것은 쉬웠습니다. 로직 (logic)의 형태를 수정하는 것이 진짜 작업이었습니다. 이제 스크립트가 찾고 있는 설정을 찾을 수 없으면, 그렇게 말하고 실패 (fail) 처리를 합니다. "이것을 확인할 수 없습니다"와 "이것은 괜찮습니다"는 더 이상 동일한 결과가 아닙니다.
그다음 저는 처음에 하지 않았던 일을 했습니다. 의도적으로 격리 (isolation)를 깨뜨렸습니다. 제 모든 작업물이 들어있는 드라이브를 직접 가리키는 공유 폴더를 연결하고, 클립보드를 다시 켰습니다. 그러고 나서 점검을 실행했습니다.
실패했습니다. 스크립트는 두 가지 문제 모두를 지목하며 통과 (all clear) 판정을 거부했습니다.
이 과정은 약 90초 정도 걸렸으며, 이것이 제가 이 점검이 제대로 작동한다고 믿는 유일한 이유입니다. 보안 통제 (security control)가 성공을 보고하는 것을 지켜보는 것은 그 통제 장치에 대해 아무것도 증명하지 못합니다. 그것은 단지 그 통제 장치가 그러한 출력을 생성할 수 있다는 것만 증명할 뿐입니다. 통제 장치가 제대로 작동하는지는, 그것이 감시해야 할 대상을 망가뜨려 보고 그것이 이를 인지하는지 확인함으로써 배울 수 있습니다.
예상치 못했던 부분
몇 시간 후, 나는 이 모든 것을 연구하기 위해 구축했던 프레임워크의 소스 코드 (source code)를 읽고 있었습니다. 샌드박스 (sandbox) 모듈 깊숙한 곳에서, 컴퓨터가 그들의 보안 보장 (security guarantees) 중 하나를 강제할 수 없을 때 발생하는 특정 오류를 발견했습니다.
그 옆에 달린 주석에는, 실패 시 폐쇄 (failing closed)하는 것이 의도된 설계라고 적혀 있었습니다. 왜냐하면 그 대안은 보호 장치가 조용히 누락된 상태로 신뢰할 수 없는 코드 (untrusted code)를 실행하는 것이기 때문입니다.
그것은 동일한 원리입니다. 동일한 논리이며, 방향만 반대일 뿐입니다. 나의 점검 (check)은 무언가를 검증할 수 없었음에도 이를 성공으로 결론지었습니다. 반면 그들의 샌드박스는 무언가를 강제할 수 없을 때, 아예 시작 자체를 거부하는 것으로 결론짓습니다.
나는 그들의 코드를 읽기 몇 시간 전에 이미 나의 수정 사항 (fix)을 작성한 상태였습니다. NVIDIA의 팀이 나와 동일한 결론에 도달하고, 이를 주석으로 설명할 만큼 중요하게 다루고 있다는 사실을 발견한 순간, 이것은 개인적인 교훈처럼 느껴지는 것을 넘어 하나의 규칙처럼 느껴지기 시작했습니다.
내가 실제로 얻은 교훈
실패할 수 없는 제어 (control)는 제어가 아닙니다. 그것은 당신이 듣고 싶은 말을 해주는 메시지일 뿐이며, 감시하던 대상이 작동을 멈춘 후에도 한참 동안이나 계속해서 그 말을 내뱉을 것입니다.
시스템에는 이런 것들이 가득합니다. 이름이 변경된 필드 (field)를 감시하는 모니터링 규칙 (monitoring rule). 이동된 폴더를 가리키고 있는 스캐너 (scanner). 몇 달 전에 실행이 중단되었음에도 여전히 녹색(pass)을 표시하는 테스트 (test). 이 중 어느 것도 스스로를 알리지 않습니다. 그것들은 모두 모든 것이 정상인 것처럼 정확하게 보입니다. 그것이 바로 핵심이며, 고장 난 안전 점검 (safety check)의 일반적인 실패 모드 (failure mode)가 침묵인 이유입니다.
"모르겠다"와 "당신은 안전하다"는 서로 다른 상태입니다.
이 두 가지를 하나의 출력으로 붕괴시키는 모든 시스템은, 결국 당신이 안전하지 않은 상황에서도 안전하다고 말하게 될 것입니다.
내가 지금 이 사실을 아는 이유는, 바로 그런 시스템을 직접 만들었기 때문입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기