보안

브라우저가 볼트가 아니라는 증거.

Chrome과 Firefox는 비밀번호를 저장하고, 사용자 권한으로 실행되는 모든 프로그램에 이를 넘겨줘요. 이건 버그가 아니라 의도된 설계예요. 쉬운 설명과 코드, 두 가지 형태로 증거를 보여드릴게요.

쉬운 설명 버전

브라우저의 '비밀번호 관리자'는 오직 하나의 잠금장치, 즉 컴퓨터 로그인으로만 보호돼요. 노트북에 로그인하는 순간 브라우저는 저장된 모든 비밀번호를 즉시 읽을 수 있고, 내 계정으로 실행되는 다른 모든 프로그램도 마찬가지예요.

잘못된 다운로드, 수상한 브라우저 게임, 클론한 프로젝트에 포함된 오염된 패키지 하나. 항상 그렇듯 로그인된 상태에서 이게 실행되는 순간, 파일을 여는 데 걸리는 시간 만에 브라우저가 저장한 모든 비밀번호를 읽어가요. 뚫어야 할 마스터 비밀번호는 없어요. 뚫을 게 없으니까요. 브라우저는 사용자를 위해 자동으로 잠금 해제되도록 설계되었고, 멀웨어는 그저 '사용자' 행세를 하며 정중히 요청할 뿐이에요.

이건 이론적인 이야기가 아니에요. 일반 사람들이 계정을 잃는 가장 흔한 단일 경로예요. 이 멀웨어는 너무 일상적이라 '인포 스틸러(info-stealer)'라는 지루한 업계 용어까지 있어요. 비밀번호, 저장된 카드, 세션 쿠키: 내가 알아차리기도 전에 복사되어 사라져요.

해결책은 말하기 간단해요. 비밀번호는 컴퓨터의 다른 부분이 가지고 있지 않은 무언가로 잠겨야 하고, 애초에 기기 안에 저장되어 있어서도 안 돼요.

증거를 곁들인 버전

저희 말만 믿지는 마세요. Chromium과 Firefox는 오픈소스이며, 읽기 경로는 문서화되어 있고 표준적이며 짧아요. 비밀번호가 정확히 어디에 있고 어떻게 추출되는지 보여드릴게요.

Chrome(및 모든 Chromium 브라우저)

Chrome은 로그인 정보를 SQLite 데이터베이스인 Login Datalogins 테이블, password_value 열에 AES-256-GCM으로 암호화해 저장해요. AES 키는 Local State에 있으며 OS에 의해 '보호'돼요. Windows에서는 DPAPI, macOS에서는 로그인 키체인, Linux에서는 gnome-keyring/kwallet(또는 평문)을 사용해요.

직접 읽어보세요. 코드는 공개되어 있어요. 래핑된 키를 태깅하는 상수를 Chromium에서 검색해 보세요: os_cryptkDPAPIKeyPrefix. 키는 DPAPI로 래핑되고, 태깅되고, 저장된 뒤, 사용자로부터 아무것도 보호하지 못하는 단일 호출로 언래핑돼요:

const char kDPAPIKeyPrefix[] = "DPAPI";

CryptUnprotectData(&intermediate, /*ppszDataDescr=*/nullptr,
                   /*pOptionalEntropy=*/nullptr, nullptr, nullptr, 0, &output);

두 번째 시크릿도, 비밀번호도, 프롬프트도 없어요. CryptUnprotectData는 세션에서 실행되는 모든 프로세스에 키를 넘겨줘요. 이건 DPAPI 문서의 위협 모델과 정확히 일치해요. 사용자 권한으로 실행되면 그건 사용자니까요. 공격자가 할 일은 단 세 줄이에요. Local State에서 키를 읽고, 언래핑하고, Login Data의 모든 행을 AES-GCM으로 복호화하는 거예요. 인포 스틸러 멀웨어는 수년 동안 정확히 이 방식을 사용해 왔어요.

'온디바이스 암호화'도 사용자를 구해주지 못해요

Google의 해답은 동기화된 볼트를 암호화하는 6자리 PIN이에요. 2026년 5월, Phishu의 연구원들은 이 보호가 얼마나 취약한지 보여줬어요. 정교한 가짜 Google 로그인, 즉 중간자 피싱을 통해 세션과 해당 PIN을 탈취하면, 이 PIN이 동기화된 계정의 모든 비밀번호와 패스키에 대한 마스터 키가 돼요. 이를 통해 공격자는 자신의 기기를 사용자의 Google '보안 도메인'에 연결하고 전체 볼트를 그대로 동기화해요. 단 한 번에 완전히 장악하는 거예요.

설계상의 결함: Google은 이미 소유한 기기의 승인 없이 6자리 PIN만으로 기기를 연결할 수 있게 해요.

Firefox

Firefox는 로그인 정보를 logins.json에, 키를 key4.db에 보관하며, NSS의 'Secret Decoder Ring'으로 복호화해요. 이 역시 오픈소스예요: security/nss/lib/pk11wrap/pk11sdr.c. 기본 비밀번호를 설정하면 키가 해당 비밀번호로 봉인돼요.

기본적으로는 설정하지 않은 상태예요. 그래서 키는 빈 문자열로 봉인되고, 저장된 'password-check' 값이 빈 비밀번호로 복호화됨을 확인해 줘요. 프로필에서 두 파일(key4.db + logins.json)을 복사해 NSS나 오픈소스 firepwd.py로 지정하면 복호화돼요. 키가 문에 테이프로 붙어 있는 자물쇠는 자물쇠가 아니에요.

The common thread

모든 브라우저 비밀번호 저장소는 같은 구조를 가져요. 시크릿은 사용자가 작업하는 곳에 존재하고, 이미 로그인된 세션에 의해 잠금 해제돼요. 사용자 컴퓨터의 다른 부분이 해제할 수 있는 암호화는 실제로 계정을 털어가는 위협, 즉 사용자 권한으로 실행되는 코드로부터 사용자를 보호하지 못해요.

Clavitor가 이런 방식으로 읽힐 수 없는 이유

Clavitor는 볼트를 기기에 저장하지 않아요. Login Data도, key4.db도, Local State의 키도 없어요. 사용자 권한으로 실행되는 프로세스가 긁어갈 수 있는 디스크상의 아무것도 없어요.

복호화 키는 OS 로그인으로 봉인되지 않아요. Touch ID, Face ID 또는 YubiKey 같은 하드웨어 터치에서 파생되어 브라우저에서 계산되고, 단일 요청에 사용된 다음 폐기돼요. 자격 증명은 요청하는 정확한 시점에 범위가 지정된 API를 통해 가져오며 절대 캐시되지 않아요. 사용자 권한으로 실행되는 멀웨어는 빈 찬장만 마주하게 돼요.

그게 '기기에 암호화되어 저장되는 것'과 '아예 기기에 존재하지 않는 것'의 차이예요.

이제 브라우저에 비밀번호를 맡기지 마세요.

Clavitor 확장 프로그램은 브라우저처럼 자동 완성해 주면서, 볼트는 노트북이 읽을 수 없는 곳에 보관해요.