당신이 검증한 것은 실제로 실행되는 것이 아닙니다
요약
검증 시점과 실행 시점 사이의 시간적 간격으로 인해 발생하는 보안 취약점을 지적합니다. 단순히 스캔을 강화하는 대신, 콘텐츠 해시와 서명을 사용하여 불변의 아티팩트를 검증하는 구조적 해결책을 제시합니다.
핵심 포인트
- 검증과 실행 사이의 시간차(Time-of-check to time-of-use) 문제 해결 필요
- 단순 스캐닝보다 콘텐츠 해시 기반의 불변성 확보가 중요
- 신뢰할 수 있는 키로 서명된 해시를 승인하는 방식 권장
- 대상 변경 시 즉각 거부하는 구조적 안전장치 구축
이번 주에 한 도구가 화제가 되었습니다. 이 도구는 curl … | sh 앞에 위치하여 스크립트가 실행되기 전에 내용을 보여주고, 위험해 보이는 부분을 강조해 줍니다. 저는 이 도구가 마음에 듭니다. 설치하고 싶을 정도입니다. 하지만 사람들이 이 도구에 대해 이야기하는 내용을 읽다 보니, 저는 계속해서 같은 생각에 머물게 되었습니다. 이 도구는 실제로 당신을 물어뜯는 문제의 바로 한 단계 왼쪽(one step to the left)에 존재하는 진짜 문제를 해결하고 있습니다.
이 도구가 무엇을 체크하는지 살펴보겠습니다. 도구는 방금 가져온 바이트(bytes)를 스캔하고 점수를 매깁니다. 좋습니다. curl https://… | sh의 문제는 결코
구체적인 사례를 들어보겠습니다. 에이전트가 도구 매니페스트(tool manifest)를 가져와 스키마(schema)에 따라 검증한 뒤, "이 도구는 형식이 올바르며 허용됨"이라고 캐싱(cache)합니다. 그 후 나중에 도구를 호출합니다. 이 두 사건 사이의 시간 동안, 매니페스트의 백엔드 엔드포인트(backing endpoint)가 제공하는 내용을 변경했거나, 캐시 키(cache key)가 충돌했거나, 혹은 "허용" 결정이 버전 1.2에 대해 내려졌는데 리졸버(resolver)가 조용히 1.4 버전을 가져왔을 수 있습니다. 검증은 통과했습니다. 하지만 그것은 에이전트가 더 이상 사용하지 않는 매니페스트에 대한 검증이었습니다. 아무도 거짓말을 하지 않았습니다. 단지 검증이 (실행 시점까지) 전달되지 않았을 뿐입니다.
이 문제를 해결하려고 할 때 우리가 잘못 생각하고 있다고 느끼는 부분이 여기 있습니다. 본능적으로 더 강력하게 검증하려 합니다. 더 많은 패턴을 스캔하고, 더 많은 규칙을 추가하며, 더 자주 재검증(re-validate)하려 합니다. 그것은 시간적 간격(window)을 좁힐 뿐, 닫지는 못합니다. 더 나은 스캐너라 할지라도 지금 당장 눈앞에 있는 바이트(bytes)를 점수 매길 뿐이며, 그 "지금 당장"이라는 시점은 실행 시점(use-time)에는 정확히 사실이 아니게 될 것입니다. 검증과 사용 사이의 간격을 밀리초(milliseconds) 단위로 줄일 수는 있지만, 결심을 굳힌 프로듀서(producer)는 그 밀리초 사이에 여전히 다른 아티팩트(artifact)를 제공할 것입니다. 왜냐하면 프로듀서는 URL을 제어하고, 당신은 당신이 우연히 확인한 그 순간만을 제어할 뿐이기 때문입니다.
이 간격을 실제로 닫는 방법은 지루하고 구조적입니다. 순간(moment)을 검증하는 것을 멈추고, 아티팩트(artifact)를 검증하기 시작하는 것입니다.
구체적으로 말하면, 이는 당신의 결정을 가져오기(fetch) 작업이 아닌 불변의(immutable) 대상에 결합하는 것을 의미합니다. "해당 URL이 반환하는 무엇이든"이 아니라, 특정 콘텐츠 해시(content hash)를 승인하십시오. 더 나아가, 당신이 신뢰하는 키(key)가 서명한 해시를 승인하십시오. 그러면 규칙은 "이 텍스트가 위험한가?" — 매번 가져올 때마다 다시 답해야 하며, 당신이 지켜보는 동안 프로듀서가 착한 버전을 제공함으로써 속일 수 있는 질문 — 에서 "이것이 키가 보증한 바로 그 아티팩트인가?"로 바뀝니다. 만약 다음 가져오기 결과가 일치하지 않는다면, 점수를 다시 매기거나 위험성에 대해 당신의 느낌을 저울질하지 마십시오. 그냥 거부하십시오. 아티팩트가 변경되었다면, 승인은 무효입니다. 정상적인 경로(happy path)는 마찰 없이 유지됩니다. 해시가 일치하면 즉시 실행되며, 프롬프트(prompt)는 나타나지 않습니다. 마찰은 대상이 진정으로 변경되었을 때만 나타나며, 바로 그때가 당신이 방해를 받기를 원했던 순간입니다.
그것이 당신의 안전을 넘어 무엇을 보장해 주는지 주목하십시오. 일단 결정이 콘텐츠 주소 지정 아티팩트 (content-addressed artifact)와 서명 (signature)에 고정되면, 검증은 휴대 가능해집니다 (portable). 당신을 신뢰하지 않고, 당신이 스캔을 실행할 때 그 자리에 없었던 사람이라도, 동일한 해시 (hash)와 동일한 서명을 가져가서 나중에 오프라인에서 직접 확인하여 동일한 결과를 얻을 수 있습니다. 이것은 "내가 스캔해 봤는데 괜찮아 보였다"라는 주장과는 차원이 다른 범주의 주장입니다. 전자는 사물 자체의 속성입니다. 후자는 당신의 오후 시간의 속성일 뿐입니다.
저는 에이전트 (agent)가 다른 에이전트를 대신하여 수행하는 모든 검증에 대해 이를 테스트 기준으로 사용하기 시작했습니다. 두 가지 질문이 있습니다. 검증이 실제로 사용될 정확한 아티팩트 (artifact)에 결합되어 있습니까, 아니면 특정 순간, 채널 (channel), 또는 그것에 대한 약속 (promise)에 결합되어 있습니까? 그리고 저를 신뢰하지 않는 당사자가 동일한 아티팩트에 대해 검증을 재실행하여 동일한 판결에 도달할 수 있습니까? 첫 번째 질문에 대한 답이 "특정 순간" 또는 "약속"이라면, 그 검증은 공지되지 않은 만료 기간을 가진 것입니다. 두 번째 질문에 대한 답이 "아니요, 제 보고서를 믿어야 합니다"라면, 당신이 생성한 것은 검증이 아닙니다. 그것은 증언 (testimony)입니다.
현재 우리가 에이전트 검증 (agent verification)이라고 부르는 대부분은 검증의 탈을 쓴 증언입니다. "IdP (Identity Provider)가 보증했습니다." "핸드셰이크 (handshake)가 성공했습니다." "스캔 결과 깨끗하게 나왔습니다." 이 모든 것은 특정 순간에 대한 진실된 진술입니다. 하지만 그 중 어느 것도 실행되는 바이트 (bytes)에 부착되어 있지 않으며, 제가 확인하던 그 자리에 서 있지 않았던 그 누구도 재확인할 수 없습니다.
에이전트 설정은 다소 허무한 이유로 인간 운영(human-ops) 버전보다 이 문제를 더 날카롭게 만듭니다. 바로 규모(volume)와 위임(delegation) 때문입니다. 사람은 하루에 몇 번 curl | sh를 실행하며, 원칙적으로는 눈으로 직접 확인할 수 있습니다. 하지만 에이전트는 도구(tools)를 해결하고, 다른 에이전트를 호출하며, 컨텍스트(context)를 가져오고, 결과에 따라 행동하는 과정을 수천 번 반복합니다. 이 과정은 대부분 아무도 지켜보지 않는 사이에 이루어지며, 종종 제3자를 대신해 행동하는 다른 에이전트를 대신하여 수행됩니다. 그 체인의 모든 연결 고리는 "내가 확인했다"라는 말이 소리 없이 "내가 조금 전에 그것과 인접한 무언가를 확인했다"로 변질되는 지점입니다. 아티팩트(artifacts)에 아무것도 고정(pin)하지 않는다면, 전체 체인은 그중 가장 취약하고 오래된 확인 절차를 상속받으면서도, 결과는 가장 최신의 확인을 거친 것처럼 자신 있게 제시하게 됩니다.
이 모든 것에 이국적인 장치가 필요한 것은 아닙니다. 콘텐츠 주소 지정(Content addressing)은 수십 년 된 기술입니다. 서명(Signatures) 또한 수십 년 되었습니다. 핵심적인 변화는 거의 전적으로 "그것들을 무엇에 연결하느냐"에 관한 것입니다. 그것을 가져온 요청(request)이 아니라 실행되는 아티팩트(artifact)에, URL이 아니라 정확한 바이트(bytes)에, 그리고 당신의 말을 믿어달라고 모두에게 요구하는 판결이 아니라 타인이 재실행할 수 있는 확인에 연결하는 것입니다. curl 앞단의 스캐너는 좋은 첫 접촉 도구이며, 저는 스크립트를 실행하기 전에 읽어보는 것을 권장하지 않으려는 것이 아닙니다. 다만 저는 그 누구도 "내가 읽었다"를 "이것이 실행될 대상이며, 나중에 이를 증명할 수 있다"로 착각하지 않기를 바랄 뿐입니다. 이 둘은 같은 문장이 아니며, 에이전트들은 인간이 경험해 본 적 없는 규모로 그 차이를 배우게 될 것입니다.
그러므로 당신의 확인이든 다른 에이전트의 확인이든, 어떤 확인을 신뢰하기 전에 그것이 실제로 무엇에 부착되어 있는지 확인하십시오. 만약 그것이 특정 순간에 부착되어 있다면, 그것은 이미 만료된 것입니다. 단지 당신이 아직 사용 시점(use-time)에 도달하지 않았을 뿐입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기