지인차단 화면의 "3명 서로 안 보임" 한 줄이 내 주소록 속 누가 이 서비스에 가입했는지를 흘리고 있었음. 이름을 안 보여 줘도 숫자만으로 새는 것들과, 번호를 받아서 버리는 방법.
아는 사람을 피하는 기능
Mbtigram은 모르는 사람과 대화하는 앱임. 그러니 아는 사람을 피하는 방법도 있어야 했음. 지인차단은 내 주소록에 있는 번호의 주인과 내가 서로 안 보이게 하는 기능임.
처음에는 번호를 한 명씩 손으로 적게 했음. 그런데 아는 사람을 피하려고 쓰는 기능에서 주소록을 하나하나 옮겨 적게 하면 아무도 끝까지 못 함. 그래서 주소록을 통째로 읽게 바꿨음.
"3명 서로 안 보임"
등록이 끝나면 "3명 서로 안 보임"처럼 결과를 보여 줬음.
그런데 이 숫자는 내 주소록의 세 사람이 이 서비스에 가입했다는 뜻임. 누구인지는 안 알려 줬어도 가입 사실은 이미 새고 있었음. 숫자로 범위를 좁힐 수도 있음. 주소록에서 한 명을 지우고 다시 등록했을 때 3이 2로 줄면 방금 지운 사람이 가입자임. 몇 번 반복하면 이름까지 나옴.
그래서 그 숫자를 없앴음. 서버는 이제 등록한 번호가 몇 개인지만 돌려줌. 그건 내가 이미 아는 정보임. 몇 명이 걸렸는지는 세지도 않고 응답에 담지도 않음. 이 뒤로는 화면에 뭘 보여 줄지 정할 때 여러 번 바꿔 보면 무엇을 알 수 있는지를 한 번 더 따져 보게 됐음.
WebView에서 주소록 읽기
Mbtigram은 웹 화면을 앱 껍데기(WebView)에 띄우는 구조인데, WebView에는 연락처를 읽을 방법이 없음. 연락처를 고르는 웹 표준(Contact Picker)은 크롬 브라우저에만 있음. 그래서 이 기능만 네이티브를 거침.
- 웹 화면이 앱에 "주소록 읽어 줘"를 요청함
- 앱이 권한을 물어봄
- 백그라운드에서 연락처를 읽음(번호만)
- 번호 목록을 웹 화면에 돌려줌
이름과 이메일은 읽지 않음. 필요도 없고, 읽는 범위가 넓어지면 스토어 심사에서 설명해야 할 것도 같이 늘어남.
권한을 묻기 전에 설명 화면을 먼저 띄움. 무엇을 읽는지, 어디에 쓰는지, 무엇을 저장하지 않는지 세 가지가 들어 있음. 구글 플레이가 이런 사전 고지를 요구하고, 설명 없이 권한 창부터 띄우면 반려됨.
서버에는 지문만 저장
번호 원본은 서버까지 감(HTTPS). 서버는 번호를 비밀 키로 섞어 되돌릴 수 없는 지문(HMAC)으로 바꾸고, 지문만 저장한 뒤 원본은 버림. 두 사람이 서로 차단 대상인지는 지문끼리 맞춰 보면 됨.
앱에서 미리 해시해서 보내면 원본이 서버에 올 일도 없겠지만 그렇게는 못 함. 번호는 경우의 수가 적어서 그냥 해시하면 전부 대입해 보는 걸로 풀림. 비밀 키를 섞어야 하는데, 그 키를 앱에 넣으면 앱을 뜯어 본 사람 모두에게 키를 나눠 주는 셈임.
같은 이유로 그 비밀 키는 절대 바꾸면 안 됨. 바꾸면 저장된 지문이 전부 다른 값이 돼서 지인차단이 조용히 다 풀림.