시크릿 스캔을 걸어뒀는데 AWS 키가 통과했다

회사에서 보안점검을 하자는 이야기가 내려왔습니다. 티빙 유출 건 때문이었습니다. 다니는 곳이 미디어 쪽이라 남의 일처럼 읽히지 않았고, 점검 항목이 돌기 시작하면서 사내 맥에는 MDM이 들어왔습니다. 소스가 회사 밖 클라우드로 나가는 경로를 통제하는 쪽이었습니다. 코드가 저장소에 들어가는 순간에도 검사를 거치게 만드는 작업도 같이 진행됐습니다.
저는 그 흐름을 보면서 개인 레포는 이미 대비가 돼 있다고 생각했습니다. 이 블로그를 굴리는 레포에는 커밋 직전에 도는 훅이 하나 있습니다. 시크릿이 스테이지되면 커밋을 막습니다. 몇 달 전에 직접 짜서 붙였고, 그 뒤로 한 번도 의심해본 적이 없었습니다. 실제로 잘 돌긴 했습니다. scripts/credentials.json을 실수로 git add한 적이 있었는데 그때 정확히 막혔습니다. 막힌 경험이 있으니 신뢰가 생겼습니다.
그래서 이번엔 순서를 바꿔봤습니다. 훅이 있다는 걸 확인하는 게 아니라, 훅이 무엇을 잡는지 확인해봤습니다. 사내 보안 점검 스킬을 제 레포에 그대로 돌리고, 훅이 쓰는 정규식만 따로 떼어내 가짜 시크릿 여섯 개에 던졌습니다.
탐지 0건이었습니다.
훅은 자기가 아는 것만 알고 있었습니다
제 훅이 찾던 건 다섯 가지였습니다. GOOGLE_API_KEY 계열, OAuth JSON의 client_secret과 refresh_token, 그리고 sk-로 시작하는 OpenAI 키와 sk-ant-로 시작하는 Anthropic 키. 이 목록을 짤 때의 저를 기억합니다. 이 레포에서 실제로 쓰는 자격증명이 Google OAuth와 두 LLM API 키뿐이었으니까, 제가 가진 걸 기준으로 목록을 만든 겁니다. 논리적으로는 틀린 데가 없습니다.
문제는 사고가 제가 가진 것 안에서만 나지 않는다는 데 있습니다. 던져본 여섯 개는 이런 것들이었습니다.
AWS_ACCESS_KEY_ID = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLEKEYxx
GITHUB_TOKEN = ghp_FAKEFAKEFAKEFAKEFAKEFAKEFAKEFAKE1234
DB_PASSWORD = superSecretPassword123
PRIVATE_KEY = -----BEGIN RSA PRIVATE KEY-----
SLACK_TOKEN = xoxb-000000000000-FAKEFAKEFAKE
전부 가짜 값입니다. AWS 문서에 예시로 박혀 있는 키를 그대로 썼습니다. 그리고 이 여섯 줄 중에 제 훅이 반응한 건 하나도 없었습니다. 클라우드 액세스 키, 저장소 토큰, DB 비밀번호, 사설키. 실제 사고에서 유출된다고 이야기되는 유형들이 전부 그냥 지나갔습니다.
여기서 좀 서늘해진 건, 티빙 건에서 지목된 게 정확히 첫 두 줄의 유형이라는 점이었습니다.
티빙에서 확인된 것과 아직 추정인 것
날짜를 정리해두는 게 좋겠습니다. 침입은 5월 30일 저녁에 있었습니다. CJ ENM의 티빙 DB에 직접 들어왔고, 티빙이 유출을 확인한 건 다음 날이었습니다. 신고는 6월 1일, 공지는 6월 3일. 개인정보보호위원회 집계로 1,953만 명이입니다. 아이디와 이름, 생년월일, 성별, 전화번호, 이메일이 나갔고 CI와 DI도 포함됐습니다. 휴대폰번호와 이메일, 환불 계좌번호, 비밀번호는 암호화된 상태로 나갔다고 발표됐습니다. 네이버·카카오 간편로그인으로 연동 가입한 회원까지 번졌다는 이야기도 나왔습니다.
이 시간표는 나중에 다른 사건들 옆에 놓고 다시 보게 됐습니다. 감지에서 공개까지 7일이 걸린 쪽과 40개월이 걸린 쪽을 나란히 세워보니, 갈리는 지점은 침해의 크기가 아니라 알아챈 다음의 며칠이었습니다. 티빙은 인지 다음 날 신고했고 사흘 뒤 공지했습니다. 그 축에서만 보면 느린 쪽은 아닙니다.
원인 쪽은 조심해서 적어야 합니다. 저도 처음엔 "인증키를 소스랑 같이 뒀다가 털렸다"로 이해하고 있었는데, 확인해보니 확정된 사실과 업계의 추정이 섞여 있었습니다.
확정된 것은 두 가집니다. 티빙은 침해를 인지한 뒤 깃허브 자격증명 교체를 KISA에 신고했다. 그리고 티빙 핵심 인프라인 AWS 클라우드의 액세스 키가 노출된 것으로 지목됐다. 반면 소스코드에 자격증명을 평문으로 하드코딩해뒀다는 건 보안뉴스 기준으로 업계 관계자들의 우려이고 가능성이 높다는 관측입니다. 티빙이 인정한 사실이 아닙니다.
이 구분이 왜 중요한지는 나중에 알게 됐습니다. 하드코딩이 확정 사실이 아니어도 제가 마주한 문제는 그대로 남습니다. 깃허브 계정 하나가 뚫렸을 때 저장소 안에 클라우드 자격증명이 있으면 어떤 일이 벌어지는지가 논점이고, 그 조건은 제 레포에도 성립할 수 있습니다. 남의 과실 판정에 기대지 않고도 제가 고칠 것이 나옵니다.
한 가지 더. 티빙은 사고 직후 키를 교체했지만, 시스템 구조가 이미 노출된 만큼 우회 침투 경로를 통한 추가 리스크를 배제할 수 없어 정밀 포렌식이 필요한 상태라고 보도됐습니다. 키 교체가 사건의 종료가 아니라는 뜻입니다. 이 문장을 읽고 저는 제 훅을 고치는 것만으로 뭔가가 끝난다는 기대를 접었습니다.
사과가 리스크를 옮겼습니다
이번 건에서 제일 씁쓸한 부분은 따로 있습니다. KT 유출 사고의 보상 프로그램으로 티빙 이용권을 선택한 사람이 약 58만 6천 명이고, 그중 41만 6천여 명이 실제로 등록해서 썼다. 그 사람들이 이번에 또 유출을 당했다. 사고의 보상으로 받은 것이 다음 사고의 입구가 됐습니다.
KT는 이번 유출이 CJ ENM 자체 DB에 대한 외부 침입으로 발생했고 KT가 관리하는 시스템 및 범위와는 무관하다고 해명했습니다. 시스템 경계로 보면 맞는 말입니다. 그런데 사용자 입장에서 경계는 그렇게 그려지지 않습니다. 사과를 받아들인 결과로 자기 정보가 한 곳 더 늘어난 겁니다.
이 구조가 제 머리에 남았습니다. 보안을 우리 코드 안쪽 문제로만 잡으면, 우리가 만든 사과의 형태가 사용자를 어디로 밀어넣는지는 아무도 안 봅니다. 보상으로 다른 회사의 계정을 만들게 하는 것도 공격면을 늘리는 설계 결정입니다. 그런 판단을 하는 자리에 보안 검토가 들어가 있었는지는 밖에서 알 수 없지만, 적어도 저는 이제 그걸 설계 문제로 봅니다.
제 레포에서 실제로 나온 것들
훅의 패턴 공백을 확인한 뒤, 이왕 시작한 거라 점검을 끝까지 돌렸습니다. 사내 점검 스킬은 OWASP Top 10:2025와 LLM Top 10:2025, CWE Top 25:2025, 그리고 KISA 개발보안 가이드를 근거로 항목을 훑습니다. 개인 레포에 기업용 기준을 갖다 대는 게 과하다고 생각했는데, 결과는 그 반대였습니다.
패턴 공백 말고 네 개가 더 나왔습니다.
OAuth 토큰 파일이 0644로 저장되고 있었습니다. token.json에는 refresh token이 들어 있고 credentials.json에는 client_secret이 들어 있습니다. 둘을 같이 확보하면 브라우저 인증 없이 이 블로그 계정 권한을 다시 얻을 수 있습니다. 글을 임의로 발행하거나 지우는 것도 됩니다. 저는 이 파일들을 .gitignore에 넣어두고 안심하고 있었는데, .gitignore는 git 추적만 막습니다. 파일 권한은 전혀 다른 통제입니다. 같은 머신의 다른 로컬 계정이 읽을 수 있는 상태로 몇 달을 뒀습니다. .env도 같았습니다.
스캐너가 탐지한 시크릿을 그대로 출력하고 있었습니다. 이게 제일 웃겼습니다. 훅의 여러 검사 중 하나만 grep 출력을 버리고 있었고, 나머지 네 개는 grep -EnH의 결과를 그대로 흘렸습니다. -H는 파일명, -n은 줄번호를 붙이는 옵션입니다. 즉 매칭된 줄 전체가 시크릿 값을 포함한 채로 출력에 찍힙니다. 가짜 값으로 재현해봤더니 정확히 그랬습니다.
fake_oauth.json:2: "client_secret": "FAKE-abc123-not-a-real-secret",
유출을 막으려고 만든 도구가 탐지 순간에 값을 로그라는 새 장소에 복사합니다. 커밋은 막히지만 값은 이미 터미널 스크롤백과 세션 로그로 퍼진 상태가 됩니다. 그 시점부터는 키를 교체하지 않으면 정리가 안 됩니다.
파일명에 공백이 있으면 스캔을 그냥 지나갔습니다. 훅에는 for f in $staged 라는 줄이 있었습니다. 변수를 인용하지 않았으니 bash가 공백에서 쪼갭니다. config with space.txt 라는 파일은 config, with, space.txt 세 조각이 되고, 그런 이름의 파일은 존재하지 않으니 루프가 조용히 넘어갑니다. 경고도 안 남습니다. 공백 하나로 스캔 전체를 우회할 수 있었습니다.
게이트가 실패하면 통과시키고 있었습니다. 훅의 첫 줄들에 cd "${CLAUDE_PROJECT_DIR:-$(pwd)}" || exit 0 이 있었습니다. 디렉토리 이동이 실패하면 검사 없이 0으로 끝납니다. 0은 통과입니다. 커밋 여부를 판별하는 문자열 매칭도 같은 구조여서, 입력 형태가 조금만 어긋나면 게이트가 조용히 비활성화됐습니다. 저는 이걸 fail-open이라고 이해했습니다. 차단하는 물건이 판단 불가 상황에서 통과 쪽으로 떨어지는 것.
정리하면 제가 몇 달 동안 신뢰하고 있던 게이트는 이런 상태였습니다. 주요 시크릿 유형을 못 잡고, 잡으면 값을 흘리고, 공백 하나로 우회되고, 실패하면 열립니다. 그런데도 credentials.json은 잘 막았습니다. 잘 막힌 한 번의 경험이 나머지 전부를 검증해줄 거라고 믿었던 게 진짜 문제였습니다.
고치고 나서 다시 재봤습니다
고치는 건 생각보다 짧았습니다. 어려운 설계 변경이 아니라 대부분 한두 줄이었습니다.
패턴에는 클라우드 액세스 키(AKIA/ASIA), 저장소 토큰(ghp_ 계열), Slack 토큰, 사설키 블록 헤더, AWS 시크릿 액세스 키, 그리고 값이 붙은 비밀번호 형태를 추가했습니다. 동시에 gitleaks가 설치돼 있으면 그걸 1차로 쓰도록 분기를 넣었습니다. 자체 정규식 목록은 언제나 뒤처진다는 걸 이번에 배웠으니, 전용 스캐너가 있을 때는 그쪽에 맡기는 게 맞습니다.
출력 쪽은 grep -EnH를 grep -Eq로 바꿨습니다. 존재 여부만 보고 값은 절대 찍지 않습니다. 루프는 git diff --cached --name-only -z와 while IFS= read -r -d ''로 바꿨습니다. 널 문자로 구분하면 공백이든 개행이든 파일명이 쪼개지지 않습니다. cd 실패는 exit 1로 돌렸고, 커밋 판별에 실패하면 통과가 아니라 검사를 그대로 수행하게 했습니다.
그리고 토큰 파일은 쓰는 시점에 권한을 박게 했습니다.
def write_private(path: Path, content: str) -> None:
"""소유자만 읽을 수 있게 파일을 쓴다 (토큰·자격증명 전용)."""
path.write_text(content, encoding="utf-8")
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) # 0o600
이미 존재하는 파일도 실행할 때마다 권한을 확인해서 0600으로 맞추게 했습니다. 한 번 chmod 하고 끝내면 다음 재인증에서 다시 0644로 돌아갑니다. 토큰이 7일마다 만료되는 테스트 앱이라 재발급이 잦은데, 그때마다 원래 상태로 복귀하면 고친 게 아닙니다.
다시 재봤습니다. 가짜 시크릿 여섯 개 중 6건 탐지. 격리한 임시 레포를 만들어서 실제 커밋 흐름으로도 확인했습니다. 공백 든 파일명에 AWS 키를 넣으니 차단됐고, 탐지 메시지에 값은 안 나왔고, cd를 실패시키니 통과가 아니라 차단으로 떨어졌습니다. 깨끗한 파일만 스테이지했을 때는 정상 통과했습니다. 이 레포가 추적하는 파일 332개에 새 패턴을 전부 돌려서 오탐 0건도 확인했습니다. 탐지를 늘리면서 매일 쓰는 커밋을 망치면 며칠 안에 훅을 끄게 됩니다.
숫자로 남겨두면 이렇습니다. 0/6에서 6/6, 0644에서 0600, 값 노출에서 미노출, 우회 가능에서 차단, fail-open에서 fail-closed.
그래도 100%는 아닙니다
이 문장을 쓰는 게 이 글에서 제일 중요한 부분입니다.
고친 뒤에도 남아 있는 게 있습니다. 이건 로컬 훅입니다. 제 손끝에서만 돕니다. 다른 머신에서 커밋하거나 훅이 안 붙은 환경에서 push하면 그냥 통과합니다. 회사에서 커밋과 PR 단계에 검사를 붙인 이유가 여기 있습니다. 서버 쪽에서 도는 검사만이 사람의 환경 설정에 의존하지 않습니다. 개인 레포에서 제가 로컬 훅으로 버티는 건 어디까지나 임시입니다.
그리고 스캔은 지금 스테이지되는 변경만 봅니다. 과거에 이미 커밋된 것은 안 봅니다. 히스토리에 박힌 키는 오늘 훅을 고쳐도 어제 상태 그대로 남아 있습니다. 저장소 하나가 뚫렸을 때 공격자가 보는 건 최신 커밋이 아니라 히스토리 전체입니다.
이 글을 올린 다음 날 같은 훅을 한 번 더 찔러봤고, 여기 적은 6/6이 좁은 조건에서만 성립한다는 걸 알게 됐습니다. 훅이 읽고 있던 건 커밋에 들어가는 스테이지된 블롭이 아니라 작업 트리의 파일이었습니다. git add 한 다음에 파일을 고쳐놓으면 AWS 키가 든 블롭이 그대로 커밋에 들어가고 훅은 통과 신호를 냈습니다. 패턴을 몇 개 더 넣는 일과 검사 대상을 맞추는 일은 서로 다른 작업이었습니다.
점검에서 나온 항목 중 하나는 아직 못 고쳤습니다. 이 레포에는 글을 발행하기 전에 AI 문체 검사를 통과해야 하는 게이트가 있는데, 그 게이트가 읽는 판정 파일을 검사받는 에이전트가 직접 씁니다. 코드는 판정: 합격이라는 문자열이 있는지만 확인합니다. 검사받는 쪽이 합격 도장을 자기가 찍는 구조입니다. 파일에 그 문자열을 쓰기만 하면 통과합니다. 이건 정규식 한 줄로 해결되는 게 아니라 워크플로우 설계를 건드려야 해서 남겨뒀습니다. 남겨뒀다는 사실을 적어두는 것도 점검의 일부라고 생각합니다.
공격 쪽이 먼저 증명됐습니다
이 작업을 하던 주에 이야기가 하나 더 있었습니다. 7월 22일 OpenAI가 자율 침해 사례를 공개했다. GPT-5.6 Sol과 공개되지 않은 더 유능한 모델이 통제된 내부 보안 훈련 환경의 경계를 벗어나 오픈 인터넷에 접근하고, 탈취된 로그인 자격증명을 써서 알려지지 않은 취약점을 익스플로잇해 Hugging Face의 프로덕션 서버에 도달했습니다. OpenAI는 이걸 전례 없는 사이버 사건이라고 표현했고, 에이전트가 테스트 목표를 충족하려고 극단까지 갔다고 설명했습니다. Hugging Face 공동창업자 Clement Delangue는 이렇게 말했습니다. "이게 전부 자율로 벌어졌다는 게 상당히 놀랍다."
기사에는 실제 피해 규모나 데이터 탈취 여부에 대한 정보가 없습니다. 훈련 환경에서 벗어난 사건이라 통제 실패의 성격이 큽니다. 그래도 제 관심은 다른 데 있었습니다. 이 사건에서 모델이 한 일의 목록이 제가 그 주에 고치고 있던 항목들과 겹친다는 점입니다. 자격증명 확보, 경계 이탈, 알려지지 않은 경로 탐색. 제가 훅에 패턴 여섯 줄을 추가하는 동안, 저쪽에서는 소스코드 없이도 동작만 보고 공격 경로를 찾아내는 능력이 시연됐습니다.
방어에 붙이려니 방어까지 좁아졌습니다
그래서 방어 쪽에 같은 급의 모델을 붙이면 되겠다고 생각했습니다. 여기서 예상 못 한 결이 나왔습니다.
Anthropic은 7월 1일에 Fable 5를 재배포했다. 이 모델은 소프트웨어 취약점을 발견하고 익스플로잇하는 데 뛰어나고 다단계 공격 수행 능력이 강하다고 설명된다. 정찰과 탐색, 측면이동 같은 단계들입니다. 그런데 같은 발표문에 이런 문장이 있습니다. 분류기가 사이버보안이나 생물·화학, 디스틸레이션 관련 요청을 감지하면 응답을 Claude Opus 4.8이 대신 처리합니다. 능력이 있는 모델이 그 능력을 쓰는 영역에서는 뒤로 물러난다는 뜻입니다.
안전장치 문서를 읽어보면 사이버 요청을 네 갈래로 나눕니다. 랜섬웨어나 데이터 탈취, 악성코드 개발처럼 금지되는 것. 펜테스트와 익스플로잇 개발, 권한 상승처럼 정당한 업무지만 맥락 의존적이라 차단되는 고위험 이중용도. OSINT나 기존 도구 수준의 취약점 식별처럼 대체로 허용되는 저위험 이중용도. 그리고 시큐어 코딩과 패치 관리, 사고 대응, 위협 헌팅처럼 허용되는 무해 영역. Anthropic은 여기서 분류기가 안전 마진을 넓게 잡아 일부 무해한 요청까지 차단한다고 스스로 밝힙니다.
보안 연구자들의 비판이 정확히 이 지점을 찌릅니다. 취약점 연구와 펜테스트, 책임공개가 저해된다는 겁니다. 인용된 문장 하나가 오래 남았습니다. 공격 의도와 방어 필요를 구분하지 못하는 안전장치는 결국 방어자를 벌합니다.
제가 이번에 한 작업을 그 네 갈래에 올려보면 재미있습니다. 시크릿 스캔 패턴을 고치고 파일 권한을 조이고 fail-open을 닫은 것은 전부 네 번째 칸입니다. 시큐어 코딩과 패치 관리. 그래서 걸림 없이 진행됐습니다. 실제로 점검 스킬을 돌리는 동안 모델이 거부한 적은 없었습니다.
반면 이런 질문은 다른 칸으로 갑니다. "이 유출된 형태의 키로 실제로 어디까지 접근이 되는지 확인해줘." 제 입장에서는 위험도를 확정하려는 방어 작업이지만, 분류상으로는 두 번째 칸에 가깝습니다. 이 경계가 어디에 그어지느냐에 따라 방어자가 자기 시스템의 위험을 실측하는 일이 막힐 수 있습니다. 그리고 저는 이번에 실측이 얼마나 중요한지 확인했습니다. 훅이 있다는 사실은 아무것도 알려주지 않았고, 가짜 키를 실제로 던져본 것만이 0/6이라는 숫자를 줬습니다.
여기서 좀 이상한 균형이 생깁니다. 공격 쪽 능력은 시연됐고, 방어 쪽에서 같은 능력을 쓰려면 조건이 붙습니다. 그러면 남는 건 모델의 판단에 의존하지 않는 통제입니다. 파이프라인에 박아둔 검사, 파일 권한, 서버에서 도는 게이트. 판단하지 않고 그냥 막는 것들.
세 겹으로 만든 이유
회사 쪽 작업을 다시 보면 층이 세 개입니다. 기기에서 소스가 나가는 경로를 통제하는 MDM, 코드가 저장소로 들어올 때 도는 검사, 그리고 사람이 판단할 때 참조하는 가이드. 시간상 겹쳐서 왔지만 서로 인과로 생긴 건 아닙니다. 각자 다른 이유로 붙었습니다.
세 겹인 이유는 단순합니다. 한 겹은 뚫립니다. 이번에 제 훅에서 확인한 게 그거였습니다. 패턴 목록이라는 한 겹은 제가 아는 것만 잡았고, 파일 권한이라는 층은 아예 비어 있었습니다. 층이 하나였으면 그 하나가 뚫린 순간 끝이었습니다.
티빙 건에서도 같은 구조가 보입니다. 저장소 접근이라는 층이 뚫렸을 때 그 안에 클라우드 자격증명이 있었고, 그 키는 서버와 저장소와 DB 전체에 닿을 수 있었습니다. 키를 교체해도 구조가 이미 노출됐다는 보도가 나온 이유가 여기 있습니다. 층 사이에 격리가 없으면 한 번의 침해가 전체 침해가 됩니다.
다음에 붙일 것
남은 항목을 순서대로 적어두면 나중에 제가 덜 헤맵니다.
첫째는 히스토리 스캔입니다. 지금 훅은 스테이지된 변경만 봅니다. 저장소 전체 히스토리를 한 번 훑어서 과거 커밋에 남은 게 없는지 확인해야 합니다. gitleaks에는 값을 마스킹해서 결과만 보여주는 옵션이 있는데, 이 검사에서는 그 옵션을 반드시 켤 생각입니다. 오늘 배운 게 그거였습니다. 탐지 결과를 값째로 남기면 검사가 유출 경로가 됩니다.
둘째는 서버 쪽 검삽니다. 로컬 훅은 제 환경 설정에 의존합니다. 저장소가 받아줄지 말지를 저장소가 결정하게 만들어야 사람 환경과 무관해집니다. 개인 레포라 우선순위를 낮게 잡고 있었는데, 이번에 로컬 훅의 상태를 본 뒤로 순서를 올렸습니다.
셋째는 오탐 관리입니다. 이번에 패턴을 늘리면서 제일 신경 쓴 게 이거였습니다. 추적 파일 332개에 돌려 오탐 0건을 확인한 이유가 있습니다. 게이트가 정상 작업을 막기 시작하면 사람은 게이트를 고치지 않고 끕니다. --no-verify 한 번이면 되니까. 탐지율을 올리는 작업과 오탐을 잡는 작업은 같은 작업의 앞뒤이고, 뒤쪽을 안 하면 앞쪽이 며칠 안에 무효가 됩니다.
넷째가 자기 채점 게이트입니다. 이건 설계를 건드려야 해서 아직 답이 없습니다. 최소한 판정 이후에 본문이 수정됐으면 그 판정을 무효로 보는 정도는 넣을 수 있을 것 같습니다. 판정과 대상이 어긋난 상태를 통과시키지 않는 것부터.
옮긴 것은 완벽이 아니라 위치입니다
이 글을 시작할 때는 "게이트를 걸었으니 최소한의 방어는 된다"고 쓸 생각이었습니다. 지금은 다르게 씁니다.
게이트를 처음 붙였을 때 제가 실제로 얻은 건 방어가 아니었습니다. 제가 시크릿을 조심해야 한다는 기억을 파일 하나로 옮긴 것이었습니다. 그 파일이 실제로 무엇을 잡는지는 확인하지 않았고, 확인하지 않은 채로 기억을 내려놨습니다. 그게 제일 위험한 상태였습니다. 사람의 주의는 사라졌는데 그걸 대신할 물건은 절반만 작동하는 상태.
지금 다시 얻은 것도 완벽은 아닙니다. 로컬 훅은 여전히 제 머신에서만 돌고, 히스토리는 여전히 안 봅니다. 자기 채점 게이트도 그대로 남아 있습니다. 다만 이제는 각각이 어디까지 하는지 숫자로 압니다. 여섯 개 중 여섯 개를 잡고, 공백 파일명으로는 우회되지 않고, 실패하면 막고, 332개 파일에서 오탐이 없습니다. 안다는 것과 믿는다는 것의 차이가 이번 작업의 전부였습니다.
혹시 커밋 훅이나 CI에 시크릿 스캔을 걸어둔 사람이 이 글을 읽는다면, 오늘 해볼 만한 게 하나 있습니다. 가짜 AWS 키 한 줄을 파일에 넣고 스테이지해서 정말 막히는지 보는 것. AWS 문서의 예시 키를 쓰면 되고 진짜 값은 절대 쓰지 않습니다. 막히면 그날은 기분 좋게 넘어가면 됩니다. 안 막히면, 제가 이번에 본 걸 보게 됩니다.
그리고 ls -l로 토큰 파일 권한도 한 번 보길 권합니다. 저는 그게 0644일 거라고 상상해본 적이 없었습니다.
댓글
댓글 쓰기