비밀값을 안전하게 저장하려고 쓴 명령어였습니다. 그 한 줄로 토큰을 그대로 노출시켰습니다.
무슨 일이었나
서버에 API 토큰을 등록해야 했습니다. 코드에 박으면 안 되니 비밀값 저장소를 쓰는 게 맞습니다. 그래서 이렇게 쳤습니다.
npx wrangler secret put xxxxxxxxxxxxxxxx <- 여기에 진짜 토큰을 그대로 쳤습니다
성공했다는 메시지가 떴습니다. 그런데 잠시 뒤 대시보드를 보니 이렇게 돼 있었습니다.
Secrets
xxxxxxxxxxxxxxxx ← 토큰이 "이름" 칸에 박혔습니다
★그 자리는 값이 아니라 이름 칸이었습니다.
올바른 사용법은 이렇습니다.
npx wrangler secret put ACCESS_TOKEN
# 그러면 값을 물어봅니다. 거기에 토큰을 넣습니다.
즉 제가 한 건 토큰을 이름으로 삼아 빈 비밀값을 만든 것이었습니다. 값은 숨겨지지만 이름은 목록에 그대로 보입니다.
왜 못 알아챘나
세 가지가 겹쳤습니다.
- 오류가 안 납니다. 이름 규칙에만 맞으면 뭐든 이름이 될 수 있습니다.
- 성공 메시지가 뜹니다. "등록됐습니다"를 보고 끝냈습니다.
- 비슷한 다른 명령들은 값을 인자로 받습니다. 환경변수 설정이 대개 그렇습니다. 손이 그 습관대로 움직였습니다.
이건 비밀값 도구에서 특히 위험한 조합입니다. 이 도구를 쓰는 목적 자체가 "화면에 남기지 않기"인데, 잘못 쓰면 가장 남기면 안 되는 곳에 남습니다.
같은 날 걸린 형제 문제
토큰을 확인하려고 이렇게 쳤습니다.
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/me
윈도우 PowerShell에서는 curl 이 진짜 curl이 아닙니다. 내장 명령의 별칭이고, 옵션 문법이 다릅니다. 엉뚱하게 해석되면서 토큰이 그대로 오류 메시지에 실려 출력됐습니다.
진짜를 쓰려면 확장자까지 적어야 합니다.
curl.exe -H "Authorization: Bearer $TOKEN" https://api.example.com/me
수습
- 토큰을 먼저 폐기했습니다. 지우는 것보다 무효화가 먼저입니다. 지워도 이미 봤을 수 있으니까요.
- 새 토큰을 발급해 올바른 방식으로 다시 넣었습니다.
- 이름이 토큰인 비밀값을 삭제했습니다.
순서가 중요합니다. 당황해서 목록부터 지우면 노출된 토큰은 여전히 살아 있습니다.
지금은 이렇게 합니다
비밀값은 인자로 절대 넘기지 않는다
도구가 인자를 받더라도 쓰지 않습니다. 표준입력으로 흘려 넣습니다.
cat token.txt | npx wrangler secret put ACCESS_TOKEN
rm token.txt
이러면 명령 기록에도, 화면에도 남지 않습니다.
명령 기록을 정기적으로 본다
셸 히스토리 파일은 평문입니다. 인자로 넘긴 비밀값은 전부 거기 남아 있습니다. 유출은 대시보드가 아니라 여기서 나는 경우가 더 많습니다.
등록한 뒤 목록을 눈으로 확인한다
npx wrangler secret list
이름이 ACCESS_TOKEN 인지, 아니면 알 수 없는 긴 문자열인지. 10초면 됩니다. 저는 이걸 안 해서 몰랐습니다.
후일담 — 이틀 뒤
이 글을 쓰고 이틀 뒤, 다른 일로 비밀값 목록을 열었다가 그때 유출한 항목이 아직 그대로 있는 걸 봤습니다.
secret list
DATA_KEY
xxxxxxxxxxxxxxxx... <- 이게 아직 있었습니다
ACCESS_TOKEN
토큰은 이미 폐기했고 새 걸로 갈아 끼웠습니다. 그러니 동작에는 아무 문제가 없었습니다. 그래서 안 지웠습니다. 정확히는, 지워야 한다는 걸 잊었습니다.
★사고는 고쳤는데 흔적을 안 치웠습니다.
목록을 여는 사람에게는 그 문자열이 계속 보입니다. 이미 죽은 토큰이라 악용될 일은 없지만, 다음에 이 목록을 보는 사람은 그게 죽은 건지 산 건지 모릅니다.
지우고 나서 이런 규칙을 더했습니다.
비밀값을 폐기했으면, 그 자리도 같이 지운다. 폐기와 정리는 한 벌이다.
고장이 안 나는 잔해는 영원히 남습니다. 아무도 불편하지 않으니까요.
가져갈 것
- 비밀값 명령의 인자 자리는 대체로 "이름"입니다. 값이 아닙니다.
- 비밀값은 표준입력으로. 인자로 넘기면 히스토리에 평문으로 남습니다.
- 노출됐을 때는 폐기가 먼저, 삭제가 나중입니다.
- 등록 후 목록을 한 번 보세요. 성공 메시지는 "제대로 넣었다"는 뜻이 아닙니다.
- 윈도우에서
curl은 진짜 curl이 아닙니다.curl.exe를 쓰세요.
제일 아팠던 건 비밀을 지키려는 행동이 곧 유출이었다는 점입니다. 안전한 도구를 쓴다는 사실이 안전을 보장하지 않습니다.
만든 것들
'Coding, Testing, Challenge' 카테고리의 다른 글
| 타임아웃을 30초로 걸었는데 410초를 모두 돌았다. (0) | 2026.09.11 |
|---|---|
| 테스트는 전부 초록불인데, 그 컬럼은 없었습니다 (0) | 2026.09.07 |