구글과 네이버는 왜 비밀번호를 평문으로 보낼까? (개발자 도구의 착시와 HTTPS의 진실)
개발자 도구에 보인 값을 네트워크 평문으로 오해했습니다
로그인 기능을 구현하면서 브라우저 개발자 도구의 Request Payload에 입력한 비밀번호가 그대로 보이는 것을 확인했습니다. 당시에는 이 화면이 실제 네트워크 구간에서도 같은 값이 노출된다는 뜻이라고 오해했습니다.
그 오해에서 출발해 비밀번호를 브라우저에서 한 번 암호화한 뒤 서버에서 복호화하는 로직을 직접 구현했습니다. 그러나 구현을 검토하면서 개발자 도구가 보여 주는 애플리케이션 내부의 요청 데이터와 HTTPS의 TLS가 보호하는 네트워크 전송 구간은 서로 다른 경계라는 점을 이해했습니다.
프론트엔드에 함께 배포되는 키는 비밀이 아니었습니다
비밀번호를 클라이언트에서 복호화 가능한 방식으로 암호화하려면 브라우저 코드에도 그 처리 로직과 키 정보가 포함됩니다. 이 프로젝트에서 시도한 구조에서는 사용자가 내려받는 프론트엔드 코드에서 키를 확인할 수 있어, 비밀번호 전송에 별도의 비밀 경계를 추가했다고 보기 어려웠습니다.
구글과 네이버의 로그인 요청도 개발자 도구에서 직접 확인했습니다. 두 서비스 역시 HTTPS 위에서 비밀번호를 별도의 클라이언트 암호화 없이 요청 본문에 담아 보냈습니다. 이 관찰은 외부 서비스의 전체 보안 구조를 분석했다는 뜻이 아니라, 개발자 도구에 Payload가 보이는 것과 네트워크 구간의 보호가 같은 문제가 아니라는 점을 확인한 계기였습니다.
비밀번호 전송용 암호화만 제거했습니다
이후 비밀번호 전송을 위해 추가했던 클라이언트 암호화를 제거했습니다. 서버에서는 전달받은 비밀번호를 bcrypt로 해시해 저장하는 구현을 사용했습니다. 전송 구간은 HTTPS, 저장 구간은 서버의 단방향 해시라는 서로 다른 책임으로 정리했습니다.
이 결정은 클라이언트 암호화를 모두 없앴다는 뜻이 아닙니다. 현재 코드에도 예약 임시 데이터와 이메일을 sessionStorage에 보관할 때 사용하는 AES 유틸리티가 남아 있습니다. 제거 범위는 비밀번호 전송을 위해 별도로 추가했던 로직으로 한정합니다.
보이지 않게 만드는 것과 보호하는 것을 구분합니다
현재의 판단은 개발자 도구에서 값이 보이는지보다 데이터가 어느 경계를 지날 때 어떤 보호를 받는지 먼저 확인해야 한다는 것입니다. 이 프로젝트에서는 HTTPS가 적용된 전송 구간과 서버 bcrypt 저장을 기준으로 삼았고, 브라우저에 함께 배포되는 키로 비밀번호를 한 번 더 감싸는 방식은 유지하지 않았습니다.
다만 이 경험만으로 모든 애플리케이션 계층 암호화가 불필요하다고 일반화하지 않습니다. 여기서 확인하고 제거한 것은 브라우저에 키가 함께 배포되던 비밀번호 전송용 추가 암호화입니다. 과거 구현 이력은 사용자 경험에 근거한 보고값이며 현재 저장소에서는 제거 전 커밋을 다시 확인하지 못했습니다.