본문으로 건너뛰기
NEW: RSAC 2026 NHI 현장 리포트. 비인간 아이덴티티가 사이버보안의 중심축이 된 이유
블로그로 돌아가기

대시보드는 시크릿 14,000개라고 합니다. 의미 있는 숫자는 525개입니다

시크릿 스캐너는 늘 큰 숫자를 내놓습니다. 그리고 그 숫자로 할 수 있는 일은 거의 없습니다. 탐지된 건을 하나씩 발급 서비스에 물어 검증했더니 다섯 자리 탐지 건수가 실제로 작동하는 크레덴셜 세 자리로 줄었습니다. 이 붕괴가 우선순위와 억제 정책, 그리고 경영진 보고에 무엇을 의미하는지 정리했습니다.

김동현
작성자
9 3,236 단어
Share:
대시보드는 시크릿 14,000개라고 합니다. 의미 있는 숫자는 525개입니다

들어가며

시크릿 스캐닝 대시보드를 열고 맨 위 숫자를 보십시오. 그리고 그 숫자로 무엇을 할 수 있는지 자문해 보십시오.

저희 숫자는 약 14,000이었습니다. 연결된 모든 소스에서 나온 크레덴셜 탐지 건수입니다. 코드 저장소, 클라우드 스토리지, 협업 도구를 전부 합친 값입니다. 정직하게 산출된 숫자이고 기술적으로 틀린 데도 없습니다. 대부분의 스캐너가 사용자 앞에 내놓는 숫자이자, 이사회 자료와 예산 요청서에 실리는 숫자이기도 합니다.

그다음 저희는 그 탐지 건 하나하나에 더 좁은 질문을 던졌습니다. "이게 크레덴셜처럼 보이는가"가 아니라 "이 크레덴셜이 지금 작동하는가"입니다. 후보 문자열을 각각 발급 서비스로 보내고 상태 코드가 아니라 응답 본문을 읽었습니다.

살아 돌아온 것은 525개였습니다.

이 격차는 탐지기의 버그가 아닙니다. 두 숫자 모두 맞습니다. 다만 서로 다른 질문에 답할 뿐입니다. 그리고 그중 하나만이 실제로 손댈 수 있는 노출을 설명합니다. 잘못된 쪽을 고르면 이번 분기에 팀이 무엇을 할지, 감사에 무엇을 답할지, 스스로 리스크를 얼마로 믿을지가 조용히 전부 어긋납니다.

후보의 개수는 인벤토리가 아닙니다

탐지는 문자열에 대한 주장입니다. 이 문자 배열이 크레덴셜의 형태를 하고 있다는 뜻입니다. 유용한 주장이고 대규모로 만들어내기에 저렴합니다.

인벤토리는 접근 권한에 대한 주장입니다. 이 크레덴셜이 존재하고 작동하며 오늘 누군가 또는 무언가가 살아있는 시스템에 쓸 수 있다는 뜻입니다. 이 주장은 훨씬 비쌉니다. 정직하게 만드는 방법이 실제로 그 크레덴셜을 써보는 것 하나뿐이기 때문입니다.

많은 보안 조직이 첫 번째 숫자를 두 번째 숫자인 양 다룹니다. 그럴 만합니다. 공짜로 나오고, 주목을 정당화할 만큼 크고, 소스를 더 연결할수록 우상향합니다. 문제는 그 숫자로 실제 작업을 하려는 순간 시작됩니다. 14,000건은 사람 손으로 분류할 수 없습니다. 그래서 표본만 보거나, 심각도 휴리스틱으로 정렬하거나, 조용히 뒤로 밀립니다. 그러는 동안 공격자를 실제로 들여보낼 그 부분집합은 노이즈와 구분되지 않은 채 더미 속 어딘가에 앉아 있습니다.

이 구조를 시크릿 스캐너에서 오탐이 생기는 이유와 능동 검증이 그것을 어떻게 해결하는지에서 다룬 적이 있습니다. 이 글은 그 검증이 실제로 돌기 시작한 뒤 숫자와 의사결정에 무슨 일이 벌어지는지를 다룹니다.

나머지 13,000은 어디로 갔나

이 붕괴는 하나의 현상이 아닙니다. 여러 가지가 겹친 결과입니다. 각각 다른 교훈을 담고 있어서 나눠 볼 가치가 있습니다.

애초에 크레덴셜이 아닌 것이 있었습니다. 토큰처럼 생긴 UUID, 커밋 SHA, base64 조각, 벤더 문서에서 그대로 옮겨온 플레이스홀더입니다. 탐지기가 그 문자열의 정체부터 잘못 본 경우입니다.

이미 폐기되었거나 만료된 크레덴셜도 있었습니다. 진짜 키이고 식별도 정확했지만 남은 권한이 없습니다. 팀이 시간을 가장 많이 낭비하는 유형이 이쪽입니다. 문자열 자체는 진짜로 민감해 보이기 때문에 사고로 취급하고 싶어지기 때문입니다.

같은 시크릿의 중복도 있었습니다. 세 개 브랜치의 설정 파일 네 곳에 커밋된 크레덴셜 하나는 크레덴셜 1개이자 탐지 4건입니다. 크레덴셜이 아니라 탐지 건수를 세면 리스크는 한 단위도 늘지 않은 채 숫자만 부풀어 오릅니다.

그리고 아무 의미 없는 범위에 묶인 것들이 있었습니다. 샌드박스 키, 로컬 테스트 픽스처, 프로덕션 데이터가 뒤에 없는 서비스의 데모 토큰입니다.

이 네 가지 중 어느 것도 탐지의 실패가 아닙니다. 시크릿일 가능성이 있는 모든 것을 잡도록 설계된 시스템이 남기는 당연한 잔여물입니다. 실패는 거기서 멈춘 뒤 그 합계를 리스크 수치라고 부르는 데서만 발생합니다.

흔하다는 것이 무해하다는 뜻은 아닙니다

억제 정책에 대한 저희 생각을 바꿔놓은 관찰이 하나 있습니다.

데이터에서 가장 흔한 단일 시크릿은 40,000곳이 넘는 자리에 있었습니다. Slack incoming webhook URL 하나가 저장소와 스크립트와 설정 파일로 복사되고 또 복사되어 사실상 어디에나 있는 상태였습니다.

모든 직관이 억제하라고 말합니다. 그 정도로 흔한 문자열이면 튜토리얼 샘플이거나 공용 픽스처이거나 오래전에 교체된 값일 가능성이 높습니다. 빈도는 무해함의 대리 지표처럼 보입니다. 그렇게 처리했다면 탐지 건수의 상당 부분을 한 번에 걷어낼 수 있었습니다.

그 웹훅은 살아 있었습니다. 호출했다면 실제 워크스페이스의 실제 채널에 메시지가 올라갔습니다.

지금까지 저희가 쓰고 싶었던 모든 빈도 기반 억제 규칙에 대한 반론이 여기 있습니다. 흔하다는 사실은 그 문자열이 어떻게 퍼졌는지를 알려줍니다. 뒤에 있는 크레덴셜이 아직 작동하는지에 대해서는 아무것도 알려주지 않습니다. 탐지 건을 종결시킬 수 있는 것은 검증뿐입니다. 개수로 억제하는 규칙은 언젠가 반드시 가장 중요한 건을 억제합니다. 하필 그것이 가장 멀리 퍼졌기 때문입니다.

이는 시끄러운 탐지를 낮추라는 통상의 조언과 정면으로 부딪힙니다. 민감도 조정은 탐지 문제를 고치는 방법입니다. 검증 문제를 고치는 방법이 아닙니다. 여기서 조정에 손을 대면 마음에 안 드는 숫자를 보이지 않는 노출과 맞바꾸게 됩니다.

숫자를 정직하게 유지하는 세 번째 칸

큰 숫자보다 더 나쁜, 작고 만족스러운 숫자를 얻는 방법이 있습니다.

검증 결과가 유효와 무효 두 가지뿐이라면 확인하지 못한 크레덴셜은 전부 무효로 분류됩니다. 검증기가 없었을 수도 있고, 네트워크가 끊겼을 수도 있고, 룰 이름이 바뀌었을 수도 있고, 그 서비스용 검증기가 아직 안 쓰였을 수도 있습니다. 2상태 시스템에서는 이 모든 것이 "죽음"으로 읽힙니다. 숫자는 내려가고 대시보드는 훌륭해 보입니다. 그동안 살아있는 크레덴셜이 해결된 더미 안에 앉아 있습니다.

검증에는 세 가지 결과가 필요합니다. 유효, 무효, 그리고 판단 불가입니다. 판단 불가는 절대 무효로 접히면 안 됩니다. 서비스가 이 크레덴셜은 못 쓴다고 답하면 그건 행동의 근거가 됩니다. 확인 자체를 못 했다면 아는 것이 없습니다. 이때 유일하게 옳은 동작은 탐지 건을 열어둔 채 사람에게 드러내고 재시도하는 일입니다.

이 구분은 두 번 중요합니다. 숫자를 정직하게 유지합니다. 그리고 자동 조치의 안전장치가 됩니다. 스스로 폐기하거나 삭제하는 파이프라인은 결론이 나지 않은 결과에 대해 반드시 행동을 거부해야 합니다. 틀렸을 때의 비용이 더 이상 분류 작업 한 시간이 아니기 때문입니다. 보안 도구가 일으킨 프로덕션 장애입니다. 저희는 내부적으로 단순한 규칙을 지킵니다. 판단 불가에는 절대 자동 폐기하지 않습니다.

그래서 실제 보고 형태는 숫자 하나가 아닙니다. 셋입니다. 검증된 활성, 검증된 비활성, 그리고 검증 불가입니다. 세 번째는 자기 커버리지에 대한 지표입니다. 이 값을 지켜보는 것이 어떤 서비스에 눈이 멀어 있는지 알아내는 방법입니다.

525로는 무엇을 하나

세 자리 숫자는 다섯 자리 숫자와 완전히 다르게 움직입니다. 단지 작아서가 아닙니다.

할당할 수 있습니다. 500여 개의 크레덴셜에는 담당자를 붙일 수 있습니다. 담당자를 특정할 수 없는 건들은 반올림 오차가 아니라 그 자체로 우선순위 큐가 됩니다. 가장 날카로운 리스크는 대개 거기 있습니다. 주인을 특정할 수 없는 크레덴셜을 들여다봤을 때 나온 결론입니다.

일정을 잡을 수 있습니다. 수백 개라면 담당자가 붙은 실제 일정으로 로테이션을 돌릴 수 있습니다. 14,000건은 끝나지 않는 프로그램과 백로그가 의미 있다고 더는 믿지 않는 팀을 만들어냅니다.

방어할 수 있습니다. 감사인이나 이사회가 크레덴셜 노출이 어느 정도냐고 물을 때 "작동이 확인된 크레덴셜 525개, 그중 60%에 담당자 지정, 로테이션 일정 수립"은 지킬 수 있는 입장입니다. "탐지 약 14,000건"이라고 답하면 그중 진짜가 몇 퍼센트냐는 당연한 후속 질문이 따라옵니다. 그리고 그 답을 갖고 있지 못합니다.

움직일 수 있는 기준선이기도 합니다. 탐지 건수는 소스를 새로 연결하면 올라갑니다. 그래서 진척 지표로 쓸 수 없습니다. 검증된 활성 크레덴셜 수는 문제를 해결하면 내려갑니다. 둘 중 일한 만큼 보상해 주는 지표는 이쪽뿐입니다.

요구해야 할 숫자

이 글에서 운영상의 변화를 하나만 가져가신다면, 도구와 벤더에 던질 질문 하나로 가져가십시오. 탐지한 것 전체 중 활성으로 확인된 건 몇 건이며, 무엇으로 확인했습니까?

뒷부분을 물고 늘어지십시오. HTTP 상태 코드만 읽는 검증은 죽은 키를 살아있다고, 살아있는 키를 죽었다고 확인해 줍니다. 인식하지 못하는 크레덴셜을 담은 요청에도 200으로 답하는 API가 흔하기 때문입니다. 제대로 된 검사는 응답 본문을 읽고 그 특정 서비스에서 인증된 응답이 어떤 모양인지 압니다. 이 작업은 화려하지 않고 서비스마다 유지보수해야 합니다. 그리고 보고하는 숫자와 신뢰하는 숫자의 차이 전부가 여기서 갈립니다.

Cremit은 이 선 위에서 제품을 만듭니다. Argus는 발급 서비스에 본문 수준 검사로 탐지 건을 검증하고, 판단 불가를 일급 결과로 유지하며, 그 상태에서는 절대 자동 폐기하지 않습니다. 결과물은 보여주기용으로 작아진 대시보드가 아닙니다. 팀이 끝까지 처리할 수 있을 만큼 작고 참인 인벤토리입니다.

여러분의 스캐너는 아마 거짓말을 하고 있지 않습니다. 묻지 않은 질문에 답하고 있을 뿐입니다.

네트워크에 공유해보세요LinkedInX

이 글이 유익하셨나요?

네트워크에 공유해보세요

Share:
뉴스레터

다음 글을 메일로 받아보세요

Cremit 리서치 팀의 월간 NHI 브리프. 한 통에 핵심만 담습니다.

이메일은 공유하지 않으며, 한 번의 클릭으로 수신거부 가능합니다.