오늘 Product Hunt에 올라왔어요! 댓글 남기기
Authenticator 1.16.0이(가) 출시되었습니다. 새로운 기능 보기
보안을 검토하는 분들을 위한 기술 개요입니다. 여기 적힌 내용은 모두 소스 코드로 확인할 수 있습니다. 우리에게 불리한 부분도 빼지 않고 그대로 적었습니다.
이 확장 프로그램은 Manifest V3 기반 Chrome 확장 프로그램으로, OTPAuth를 사용해 TOTP 코드를 기기에서 생성합니다. 코드 생성, 계정 저장, 암호화에는 백엔드가 관여하지 않으며, 회원 가입이나 사용자 계정도 없습니다. 저희가 운영하는 서버는 무료 요금제와 Pro를 위한 api.authenticator.sh 하나이며(아래에서 설명합니다), 이 서버는 비밀 키, 계정 이름, 서비스 이름, 코드 중 어느 것도 받지 않습니다.
이 서버는 누구의 계정에 대해서도 키 자료를 보관하지 않습니다. 키 위탁도, 우리가 통제하는 복구 경로도 없습니다. 사용자가 비밀번호를 잊고 복구 코드까지 잃으면 우리가 해줄 수 있는 일은 없습니다. 의도된 설계입니다.
비밀번호 보호는 선택 사항이며 기본값은 꺼짐입니다. 켜면 다음과 같습니다:
데이터를 비밀번호에서 유도한 키로 직접 암호화하는 일은 없습니다. 레코드는 무작위 마스터 키가 암호화하고, PBKDF2 출력은 그 마스터 키를 감싸기만 합니다. 여기서 두 가지 결과가 따라오는데, 둘 다 중요합니다:
비밀번호 보호를 켜면 식별자와 지문을 제외한 계정 레코드 전체가 암호화됩니다. 서비스 이름도 포함되므로, 프로필이 유출돼도 사용자가 어떤 서비스에 계정을 두고 있는지는 드러나지 않습니다. 기능을 켜면 레코드를 암호화한 뒤 복호화해 대조하는 방식으로 검증하고, 그다음에야 평문 사본을 모두 제거합니다. 브라우저 로컬 저장소, 동기화, 그리고 7일치 순환 백업 스냅샷 전부가 대상입니다.
평가에 영향을 주는 부분이라 그대로 밝힙니다:
요약하면, 이것이 지키는 것은 저장된 상태의 데이터입니다. 사용 중에 이미 공격자 통제 아래 있는 기기는 지켜 주지 못하며, 지킬 수도 없습니다.
매니페스트가 선언하는 권한은 다섯 개이며, 호스트 권한은 없습니다:
콘텐츠 스크립트가 전혀 없고도, tabs·cookies·webRequest 권한도, web-accessible resources도 없습니다. 여러분이 그 페이지에서 코드를 요청하기 전까지 저희 것은 페이지에 아무것도 존재하지 않습니다. 그때 실행되는 것은 그 탭 하나와 그 호출 한 번을 위해, 여러분 자신의 클릭이 주는 허가 아래 주입되며, 뒤에 아무것도 남기지 않습니다.
카메라 QR 스캔은 팝업이 아니라 탭으로 열린 확장 프로그램 페이지에서 실행됩니다. 팝업은 포커스를 잃으면 파괴되는데, 권한 요청이 바로 그 포커스를 빼앗기 때문입니다. 여기에는 매니페스트 권한이 필요하지 않습니다. 브라우저의 표준 카메라 요청을 사용하고, 확장 프로그램 출처 단위로 부여되며 사이트 설정에서 취소할 수 있고, 사용자가 스캐너를 열기 전에는 절대 요청하지 않습니다. 영상은 기기에서 디코딩되며 전송되거나 저장되지 않습니다.
1.14.0부터 확장 프로그램은 하루에 한 번 api.authenticator.sh에 체크인합니다. 브라우저가 시작될 때나 팝업이 화면에 그려진 뒤에 이뤄지며, 코드를 표시하는 과정에 끼어드는 일은 없습니다. 요청은 정해진 필드 목록으로만 이뤄지고, src/billing/sync.ts의 함수 하나에서 만들어지며, 테스트가 그 목록을 벗어나지 못하게 붙들어 둡니다:
절대 보내지 않는 것: 비밀 키, 계정 이름, 서비스 이름, 코드, 그리고 코드를 사용하는 사이트. 서버는 엣지에서 요청을 보고 국가를 판단하며, IP 주소는 저장하지 않습니다. 삭제 페이지는 같은 설치 ID를 ?i= 매개변수로 받아, 해당 설치가 삭제되었음을 서버에 알리고 선택 사항인 설문 답변을 그 설치와 연결합니다.
이를 위해 chrome.storage.local에 보관하는 것: 설치 ID, 마지막으로 받은 서명된 정책과 라이선스, 이 설치가 보유한 라이선스 키(직접 입력했거나 이 설치에서 구매한 뒤 받은 것), 서버가 받을 때까지의 날짜별 열린 횟수, 대기 중인 이벤트. 계정 데이터는 없습니다. 동기화가 켜져 있는 동안에는 요금제 도입 이전의 설치인지 여부와 그 라이선스 키도 Chrome 동기화에 들어가, 사용자의 다른 Chrome 프로필이 이를 이어받아 Pro를 저절로 켭니다. 동기화를 끄면 둘 다 Chrome 동기화에서 삭제되고, 다시 켜면 다시 들어갑니다.
돌아오는 것, 그리고 확장 프로그램이 그것을 다루는 방식:
이 제한은 DRM이 아닙니다. 코드는 오픈 소스이며, 포크하면 제한을 없앨 수 있습니다. 결코 가능해서는 안 되는 것은 한 사람이 다른 사람의 라이선스를 얻거나 사용하는 것, 또는 다른 사람의 설치를 제한 상태로 만드는 것입니다. 그런 일은 취약점이며, 저희 보안 정책의 적용 범위에 해당합니다.
스스로 일어나는 요청은 두 가지, 시계 확인과 하루 한 번의 요금제 체크인입니다. 아래의 나머지는 모두 사용자가 눌렀기 때문에 일어납니다. Manifest V3는 원격 코드를 금지하며, 여기 있는 어느 것도 계정이나 비밀 키, 생성된 코드를 담아 보내지 않습니다. 전체 목록은 다음과 같습니다:
| 호스트 | 시점 | 사용자 데이터를 담나요? |
|---|---|---|
| time.akamai.com timeapi.io cloudflare.com | 시계 오차 확인. 캐시되며, 어느 출처에도 닿지 못하면 설정에서 그 사실을 알려 줍니다. 시계가 어긋나면 TOTP가 어긋납니다. | 아니요 |
| authenticator.sh | 설치 시 환영 페이지, 삭제 시 피드백 페이지(주소에 설치 ID가 들어 있음), 팝업에서 열었을 때의 도움말·지원 페이지. | 삭제 페이지에서만 설치 ID. 그 밖에는 아니요(일반적인 웹 서버 로그) |
| api.authenticator.sh | 하루 한 번의 요금제 체크인. 그리고 사용자가 Pro를 구매하거나, 키를 입력하거나, 구매를 복원하거나, 구독을 관리할 때의 결제·라이선스·포털 호출. | 위에 나열한 필드뿐이며 계정 데이터는 절대 담지 않습니다. 라이선스 키나 이메일 주소는 사용자가 직접 입력했을 때만 |
| checkout.stripe.com billing.stripe.com | Stripe Checkout과 고객 포털. 사용자가 Pro를 구매하거나 구독을 관리할 때 탭으로 열립니다. | 구매자가 그곳에 입력한 내용. Stripe와 Link의 자체 약관이 적용됩니다 |
| chromewebstore.google.com | 스토어 등록 페이지. 눌렀을 때만 탭으로 열립니다. 평가 안내에서는 리뷰 작성란. | 아니요(구글에는 여느 스토어 페이지 방문과 똑같이 보입니다) |
글꼴, 스크립트, 스타일, 이미지 중 어느 것도 제3자 호스트에서 불러오지 않습니다. 화면을 그리는 데 필요한 것은 모두 패키지 안에 들어 있습니다.
위 내용 중 어느 것도 그냥 믿을 필요가 없습니다. 확장 프로그램은 오픈 소스이며 모든 릴리스를 재현할 수 있습니다:
.crx를 내려받아 압축을 풉니다npm ci && npm run build를 실행합니다dist/를 압축을 푼 패키지와 비교합니다빌드된 dist/ 안 모든 파일의 SHA-256을 GitHub 릴리스마다 SHA256SUMS-v<version>.txt 파일로, sha256sum 형식으로 함께 배포합니다. 그래서 4단계는 sha256sum -c 한 번 실행으로 끝납니다. 차이는 아카이브 내부의 파일 순서와, Node 패치 버전에 따른 최소화 출력의 공백 정도로 제한되어야 합니다.
런타임 의존성은 의도적으로 적습니다. OTPAuth, React, jsQR, Zustand, Framer Motion, Lucide뿐이며 저장소에 커밋된 lockfile로 고정되어 있습니다. CycloneDX 형식의 SBOM은 요청하시면 제공합니다.
소스 코드 보기저희는 작은 독립 개발사입니다. 다음 중 하나라도 귀사 절차의 필수 요건이라면, 평가가 3주쯤 진행된 뒤보다 지금 아시는 편이 낫습니다:
대신 제공하는 것은 소스 코드의 완전한 공개, 검증 가능한 빌드, 최소한의 권한, 그리고 비밀 키, 계정 이름, 코드가 애초에 전달되지 않는 서버입니다.
취약점 제보와 보안 문의는 security@authenticator.sh로 보내주세요. 공개 정책, 적용 범위, 응답 시간, 세이프 하버 조건은 보안 정책 페이지에 있고, 무엇이 저장되고 무엇이 기기를 떠나는지는 개인정보처리방침에 정리되어 있습니다.
서면 공급업체 평가 설문에 답변하거나, 보안팀과 함께 코드를 짚어 나가는 일도 기꺼이 하겠습니다.
보안과 무관한 사안(설치, 계정 복구, 배포 과정의 청구 문의 등)은 지원 페이지을 참고하세요. 취약점 제보는 그쪽으로 보내지 말아 주세요. 그 메일함은 기밀로 취급하지 않습니다.