[제044회] 방장이 자리를 비워도 비밀번호는 깨지지 않는다! 룸 정책 및 비밀번호의 영속화와 빈방 보안
요약
P2P 채팅방의 '빈방 재개' 기능에서 발생할 수 있는 중대한 보안 취약점을 분석하고 해결했습니다. 방이 비면 메모리상의 비밀번호 정책이 사라져 외부인이 쉽게 탈취할 위험이 있었는데, 이를 막기 위해 대화 내용은 저장하지 않고 최소한의 메타데이터(정책 및 비밀번호 SHA-256 해시)만 영속화하는 보안 설계를 적용했습니다.
핵심 포인트
- 빈방 재개 시 메모리 기반 정책 유실로 인한 탈취 위험을 발견함.
- 프라이버시 보호를 위해 대화 본문이나 개인 정보는 일절 저장하지 않음.
- 방의 입장 정책과 비밀번호 해시값만 레지스트리에 최소한으로 영속화하여 보안성을 확보함.
- 경량 레지스트리 테이블을 통해 빈방 상태에서도 안전하게 방을 재개할 수 있게 됨.
안녕하세요! 2채널 호환 게시판 시스템 「つゔぁいちゃんねる (2ch.biz)」 개발 기록 제44회입니다.
지난번(제43회)에서는 난독화 카운터 패킹을 도입하여, 연속 번호 추측을 방지하면서도 '과거의 정규 ID라면 빈방을 재개할 수 있다(리오픈)'는 편리한 기능을 만들었습니다.
하지만 이 기능을 공개하자마자 보안 검증을 진행하던 개발자가 경악할 만한 중대한 보안 취약점 (security hole/vulnerability) 을 발견했습니다.
'비밀번호를 설정하고 잠가둔 방이라도, 모두가 퇴실하여 방이 비는 순간, 비밀번호를 모르는 외부인이 들어와 방을 탈취할 수 있는 것 아닌가!?'
본고에서는 서버리스 P2P 환경의 '빈방 재개'에 숨어 있던 탈취 위험의 전모와, 최소한의 메타데이터 영속화(정책/비밀번호 해시)를 통해 비밀번호를 지켜낸 보안 설계에 대해 설명합니다!
P2P 채팅에서 참가자 전원이 브라우저를 닫으면, 시그널링 서버의 인메모리 맵 (in-memory map)에서 룸 정보가 삭제됩니다.
이때, 지난번 '빈방 재개 기능'의 단순한 구현 방식으로는 다음과 같은 치명적인 탈취 시나리오가 성립하고 있었습니다.
방이 비는 순간, 방의 '열쇠(비밀번호 정책)' 설정이 메모리와 함께 사라져 버리고, 가장 먼저 들어온 사람이 비밀번호 없이 새로운 주인(호스트)이 되어버리는 것입니다.
이 문제를 해결하기 위해, 저희는 '대화 로그나 개인 정보는 일절 저장하지 않지만, 방의 입장 정책과 비밀번호의 SHA-256 해시값만 최소한으로 영속화한다' 라는 경계를 설정했습니다.
프라이버시를 극도로 보호하기 위해 테이블에 보관하는 것은 다음 메타데이터로 한정했습니다.
CREATE TABLE IF NOT EXISTS p2p_room_registry (
room_id TEXT PRIMARY KEY,
counter INTEGER NOT NULL,
...
- 채팅 본문: 1글자도 저장하지 않음 (P2P DataChannel으로 완결). -
- IP 주소나 참가자 목록: 일절 기록하지 않음. -
- 비밀번호: 원본 문자열을 가지고 있지 않고, SHA-256 해시값만 보관.
호스트가 방을 생성할 때, 카운터 발행과 동시에 레지스트리에 정책을 저장합니다.
// 방 생성 시
function registerRoomMetadata(roomId, counter, payload) {
const policy = payload.policy || 'open';
...
방이 메모리상에 존재하지 않는 경우(빈방)에도, 레지스트리에서 메타데이터를 가져와 비밀번호를 검증합니다.
// 참가 요청 수신 시
if (action === 'join' && !isCreate) {
const meta = getRoomMetadataFromDB(roomId);
...
테스트 스크립트를 실행하여 취약점이 확실히 막혔음을 확인했습니다.
// test_room_password_persistence.js 검증 내용
async function runTests() {
// 1. 비밀번호 "secret123"으로 방을 생성
...
빈방 재개 기능이 가져온 '탈취 위험'을, 경량 레지스트리 테이블을 통한 정책 및 비밀번호 해시의 영속화로 완전히 봉쇄했습니다.
이를 통해, 비밀번호를 아는 동료들만이 다음 날에도 같은 URL로 안전하게 비밀 기지를 재개할 수 있게 되었습니다.
하지만 이 완성도에 만족하려던 저희 마음에, 어떤 '엔지니어로서의 순수한 광기(탐구심)' 가 싹트고 말았습니다.
'잠깐만……. 정책이나 카운터를 검증하기 위해, 왜 서버 측에 SQLite 테이블을 가지고 있어야 하는 거지?'
'만약 URL 토큰 안에 암호화된 정책과 비밀번호 정보를 전부 채워 넣는다면, 서버의 DB조차 100% 제거할 수 있지 않을까!?'
다음 편은 P2P 개발 기록의 클라이맥스입니다.
본 서비스 : https://2ch.biz/
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기