외부 코드 리뷰가 잡아낸 사각지대 — 모든 계정의 동일 임시 비밀번호
외부 코드 리뷰를 받았습니다. critical로 분류된 1번 지적이 임시 비밀번호였습니다. 솔직히 말하면, 이건 제 손버릇에서 시작된 부채였습니다.
테스트 계정을 만들 때 저는 "zxcvasdf"를 자주 칩니다. 키보드에 손이 익어서 빠르게 칠 수 있는 값입니다. 그런데 이 값을 임시 비밀번호 기본값 상수에 그대로 박아둔 게 문제였습니다. 결과적으로 신규로 만들어지거나 비밀번호를 리셋한 모든 계정이 같은 "zxcvasdf"를 받고 있었습니다.

혼자서는 안 보이던 사각지대였습니다
이 부채가 오래 살아남은 이유가 있습니다. 이 상수는 외부에서 참조하는 곳이 0이었습니다. 코드 안에만 묻혀 있어서, 화면이나 API 어디에도 "zxcvasdf"가 드러나지 않았습니다. 그게 그나마 폭발 반경을 줄여준 방어였지만, 동시에 제 눈에는 더 안 보이게 만든 이유이기도 했습니다.
자기 코드의 이런 사각지대는 혼자 보기 어렵습니다. 손에 익은 값이라 위화감조차 없습니다. 이번에 그걸 잡아준 건 외부 코드 리뷰였습니다. 외부 시선이 들어오니, 묻혀 있던 부채가 critical 1번으로 곧장 떠올랐습니다.
혼자서는 못 보는 걸 외부 장치가 잡아내는 경험은 전에도 있었습니다. 관계 수만 건을 눈으로 검수할 수 없어서 도구에 맡긴 적이 있습니다.
임시 비밀번호를 어떻게 만들지, 세 가지 길이 있었습니다
고치는 방법은 세 가지였습니다.
1번은 출발 상태처럼 하드코딩하는 방식입니다. 편하지만 보안은 없습니다.
2번은 타임스탬프나 계정 ID로 결정적으로 생성하는 방식입니다. 매번 다른 값이 나오지만, 규칙을 알면 추측이 가능합니다.
3번은 SecureRandom으로 무작위 생성하되, 문자셋을 운영에 친화적으로 제한하는 방식입니다. 보안과 운영 편의의 균형을 잡는 길이라 3번을 골랐습니다.
SecureRandom에 메신저 친화 문자셋을 얹었습니다
임시 비밀번호 생성기를 SecureRandom 기반으로 만들고, 소문자(a-z)와 숫자(0-9) 10자로 잡았습니다. 조합 수는 36^10, 약 3,656조 가지입니다. 추측으로 뚫기에는 충분히 큰 공간입니다.
문자셋을 일부러 소문자와 숫자로만 제한한 데에는 이유가 있습니다. 임시 비밀번호는 보통 메신저로 전달되는데, 대문자나 특수문자가 섞이면 사용자가 옮겨 칠 때 입력 오류가 늘어납니다. 보안 강도를 조금 양보하더라도 운영에서 덜 깨지는 쪽을 택한 트레이드오프입니다.
이미 있던 가드 두 개는 그대로 뒀습니다. 첫 로그인 시 비밀번호를 강제로 바꾸게 하는 플래그를 유지해서, 임시 비밀번호가 노출되더라도 곧바로 무력화되게 했습니다. 그리고 평문 비밀번호는 생성 직후 한 번만 응답으로 돌려주고, DB에는 해시만 저장합니다.
이렇게 강한 임시 비번 위에 강제 변경 가드를 한 겹 더 두는 건, 가드의 적정 강도를 따로 정해본 경험과 같은 맥락입니다.

개발 편의 기본값은 운영에 남으면 부채가 됩니다
이번 일에서 남는 건 두 가지입니다.
하나는, 개발 편의를 위한 기본값이 운영까지 따라오면 보안 부채가 된다는 점입니다. "zxcvasdf" 같은 값은 악의가 있어서가 아니라 손에 익어서 박힙니다. 그래서 더 안 보입니다.
다른 하나는, 외부 시선의 가치입니다. 자기 코드의 사각지대는 위화감조차 없어서 혼자 잡기 어렵습니다. 정기적으로 외부 리뷰를 받는 의식이 있어야 묻혀 있던 부채가 표면으로 올라옵니다. 이번 critical 1번도 외부 리뷰가 없었다면 한참 더 살아남았을 겁니다.
점검 체크리스트
임시 비밀번호나 기본값을 다룰 때 다음을 점검하면 좋습니다.
개발 편의용 기본값(테스트 비번 등)이 운영 코드에 상수로 남아 있지 않은가
임시 비밀번호를 SecureRandom 같은 안전한 난수로 생성하는가
메신저 전달 등 운영 동선을 고려해 문자셋을 정했는가
임시 비밀번호 노출에 대비해 첫 로그인 강제 변경 같은 가드를 별도로 두었는가
평문은 1회만 노출하고 저장은 해시로만 하는가
정기적인 외부 코드 리뷰로 사각지대를 점검하는가
사각지대는 외부 시선이 잡아줍니다
손에 익은 값 하나가 기본값에 박혀 모든 계정으로 퍼졌고, 그걸 잡은 건 제 점검이 아니라 외부 리뷰였습니다. 강한 난수 비밀번호로 바꾸고 강제 변경 가드를 유지하는 것으로 기술적 해결은 끝났지만, 더 오래 남는 교훈은 따로 있습니다. 자기 코드의 사각지대는 위화감이 없어서, 외부 시선을 정기적으로 들이는 의식이 가장 확실한 방어라는 점입니다.