프라이버시 테스트가 데이터를 전혀 보관하지 않는 방법

프라이버시 테스트는 웹사이트가 여러분의 브라우저에 대해 무엇을 알 수 있는지를 보여 주는 도구입니다. 캔버스와 GPU 신호, 글꼴, 화면, 시간대, 언어, 네트워크 힌트, 그리고 사이트가 재방문 시 여러분을 알아볼 수 있게 하는 조용한 식별자들까지요. 그리고 이것은 신뢰성 문제를 만듭니다. 감시 기술을 시연하는 도구는 그 도구 자체의 데이터 관행으로도 판단받기 때문에, 그것은 나중에 덧붙인 정책 페이지가 될 수 없습니다. 저희 브라우저 지문 테스트 뒤에 있는 설계 규칙은 한 문장으로 말할 수 있습니다. 브라우저가 읽을 수 있는 것은 서버가 결코 보지 않는다는 것입니다. 이 글은 그 규칙의 비용과, 어디서 굽히고, 어디서 멈추는지를 설명합니다. 먼저 신호 목록을 보고 싶다면 웹사이트가 당신에 대해 아는 것부터 시작하세요. 이 글은 신호 자체가 아니라 테스트 아래의 배관에 관한 것입니다.

클라이언트 측이 먼저

브라우저 자체가 제공하는 모든 신호는 여러분의 기기에서, 탭 안의 페이지 코드에 의해 로컬로 읽히고 렌더링됩니다. 캔버스 렌더링, WebGL 렌더러 문자열, 오디오 컨텍스트 속성, 설치된 글꼴 탐지, 화면과 창 기하, 색 깊이, 터치 지원, 저장 공간 추정, 대비와 동작에 대한 미디어 쿼리까지, 모두 발견된 곳에서 계산되어 여러분이 볼 수 있는 페이지에 그려집니다. 페이지 코드만이 전체 그림을 보유하는 유일한 것입니다. 어떤 스크립트도 패널을 페이로드로 수집하지 않고, 어떤 비콘도 그것을 집으로 보내지 않으며, 어떤 분석 이벤트도 그것을 요약하지 않습니다. 완전한 지문이 브라우저를 떠나는 순간, 테스트는 스스로 경고하던 바로 그것이 되기 때문입니다.

그 순서, 즉 로컬이 먼저, 서버는 마지막, 그리고 서버는 브라우저가 정말로 혼자서는 할 수 없는 소수의 작업만을 위해 있다는 순서는 아키텍처의 특징이 아닙니다. 그것이 바로 아키텍처입니다. 대부분의 프라이버시 도구는 거꾸로 구축됩니다. 모든 것을 중앙에서 수집한 뒤 삭제하거나, 익명화하거나, 잠시만 보관하겠다고 약속하는 식입니다. 그 약속들은 지켜질 수 있지만, 약속일 뿐이며 독자는 삭제를 감사할 방법이 없습니다. 데이터를 애초에 전송하지 않는 설계는 약속을 코드 경로에 대한 사실로 대체하고, 코드 경로에 대한 사실은 네트워크 탭에서 확인할 수 있습니다. 그것이 바로 프라이버시 도구가 초대해야 할 기준입니다.

비용은 실재하며 설계상 받아들여집니다. 기기를 넘나드는 것은 아무것도 없습니다. 여러분을 따라다니는 계정도 없고, 동기화되는 기록도 없으며, 다른 노트북에서의 지문과의 비교도 없습니다. 그 모든 것은 서버가 사람마다 무언가를 보관해야 하기 때문입니다. 비교는 여러분 자신의 브라우저가 로컬로 기억하는 것과 아래에서 설명하는 익명의 일일 카운터로 제한됩니다. 어떤 기능이 서버에 완전한 지문을 필요로 한다면, 답은 더 신중한 보관 정책이 아니라 아니오입니다. 그 제약이 곧 제품입니다.

작은 엔드포인트 세 개, 서로 다른 세 가지 일

페이지 안에서는 정말로 할 수 없는 일이 세 가지 있고, 각각은 좁은 일을 맡은 작은 엔드포인트를 받습니다. 첫 번째인 /api/check/whoami는 페이지를 가져온 요청에서 어떤 서버든 이미 보는 것만 반환합니다. 도착한 그대로의 네트워크 주소, 브라우저가 그와 함께 보낸 헤더, 그리고 그 주소에 붙은 대략적인 지리 정보입니다. 그 값들을 보여 주는 것은 새로운 노출을 더하지 않습니다. 여러분이 방문하는 모든 서버는 표시하든 안 하든 그것들을 받기 때문입니다. 이 엔드포인트는 일방적인 공개를 눈에 보이는 공개로 바꿀 뿐이며, 응답을 넘어서는 아무것도 보관하지 않습니다.

두 번째인 /api/check/etag는 다음 절에서 설명하는 캐시 기반 인식을 시연하기 위해서만 존재합니다. 무작위 캐시 식별자를 나눠 주고 아무것도 보관하지 않습니다. 발급된 값들의 표도 없고, 누가 물었는지에 대한 기록도 없습니다. 세 번째는 카운터 엔드포인트입니다. 완료된 실행에서 소수의 거친 값을 받아 누적 합계를 반환하므로, 페이지는 아무도 여러분의 방문을 저장하지 않으면서 여러분의 구성이 얼마나 흔한지를 말할 수 있습니다. 각 엔드포인트는 사이트의 다른 검사기들과 마찬가지로 속도 제한이 걸려 있습니다. 작고 정직하다는 것이 무제한이라는 뜻은 아니며, 두드릴 수 있는 데모 엔드포인트는 선의를 두른 남용 표면이기 때문입니다.

페이지는 또한 브라우저에서 직접 연락하는 외부 서비스들을 명시합니다. 그 서비스들도 여러분의 주소를 보기 때문에, 그들에 대해 정직한 것이 설계의 일부이기 때문입니다. 테스트는 Cloudflare 추적 엔드포인트를 읽고, 어떤 리졸버가 여러분을 대신해 응답하는지를 드러내기 위해 DNS 에코 서비스를 조회하며, WebRTC 방식의 조회가 무엇을 알 수 있는지를 보여 주기 위해 두 개의 공개 STUN 서버에 연결합니다. 각각은 페이지 자체에, 그것이 만들어 내는 결과 옆에 이름이 적혀 있습니다. 이는 VPN 유출과 위장 검사에 저희가 적용하는 것과 같은 공개 규율입니다. 조용히 제3자에게 전화를 거는 프라이버시 테스트는 자기 자신의 교훈에서 낙제할 것입니다.

ETag 속임수, 정직하게 설명하면

ETag는 HTTP 캐싱의 평범한 한 부분입니다. 서버는 응답에 검증자를 붙이고, 브라우저는 그것을 캐시된 사본과 함께 저장하며, 다음 방문 때 브라우저는 검증자를 돌려보내 서버가 «수정되지 않음»이라고 답하고 전송을 아낄 수 있게 합니다. 속임수는 검증자가 내용을 설명할 필요가 없다는 점입니다. 서버는 방문자마다 고유한 검증자를 발급할 수 있고, 브라우저는 재검증할 때마다 그 고유한 값을 충실히 반환합니다. 그 시점에 서버는 쿠키를 전혀 설정하지 않고도 쿠키만큼이나 확실하게 브라우저를 알아봅니다. 캐시 검증이 식별자로 겸용되는 것은 브라우저가 제 일을 제대로 하고 있기 때문입니다.

그래서 쿠키를 지워도 그것은 지워지지 않습니다. 쿠키와 캐시는 별개의 저장소이며, 별개의 조작으로, 별개의 일정에 따라 비워집니다. 사생활 보호 창이나 시크릿 창이 이 속임수를 깨는 것도 그 때문입니다. 사생활 보호 창은 닫을 때 버려지는 자체의 별도 캐시로 동작하므로 검증자는 세션과 함께 사라집니다. 저희 엔드포인트는 왕복을 시연하고 아무것도 저장하지 않습니다. 인식은 304 응답 자체로, 서버가 자신의 무작위 값이 돌아오는 것을 보는 것으로 증명되며, 방문 사이에 보관된 어떤 기록으로도 증명되지 않습니다. 시연은 페이지가 닫히는 순간 끝나는데, 이는 바로 이 기술을 쓰는 실제 추적자들이 제공하지 않는 특성입니다.

정직하게 이름 붙일 가치가 있는 작은 주름이 하나 있습니다. 엣지 캐시입니다. 응답이 공유 CDN 캐시를 통과한다면 첫 번째 방문자의 식별자가 모두에게 제공될 수 있고, 시연은 각 브라우저가 자기 것을 가진 모습 대신 군중이 하나의 ID를 공유하는 모습을 보여 줄 것입니다. 그래서 이 엔드포인트는 엣지 캐싱에서 완전히 빠져나옵니다. 모든 요청은 원본에 도달하고, 모든 방문자는 새 무작위 값을 받으며, 공유 캐시는 그 어느 것도 보관하지 않습니다. 작은 설정 한 줄이지만, 메커니즘을 증명하는 시연과 실수로 그 반대를 증명하는 시연 사이의 차이입니다.

로그 대신 카운터

서버가 정말로 필요한 질문이 하나 있습니다. «나는 얼마나 특이한가?» 여러분의 GPU가 오늘 M번의 실행 중 N번 나타났다고 말할 수 있는 페이지는 신호를 나열만 할 수 있는 페이지보다 훨씬 더 교훈적입니다. 희소성이야말로 지문을 식별 가능하게 만드는 것이기 때문입니다. 그러나 뻔한 방식, 즉 모든 방문을 기록한 뒤 세는 방식으로 답한다면, 도구가 경고하는 바로 그 데이터베이스를 구축하게 됩니다. 그래서 테스트는 로그 대신 카운터를 보관합니다. 값마다 하루에 숫자 하나입니다. 운영 체제, 브라우저 제품군, GPU 문자열, 시간대, 첫 번째 언어, 화면 크기 등급, 지문 식별자의 처음 여덟 문자, 각 개별 검사의 결과, 그리고 실행 시간 구간까지, 각각이 일일 합계에 한 칸을 기여하고, 그 외에는 아무것도 보관되지 않습니다.

메커니즘보다 경계가 더 중요합니다. 완전한 지문은 전송되지 않으며, 저장되는 것은 말할 것도 없습니다. 여러분의 주소는 카운터에 전혀 전송되지 않습니다. 카운터를 거꾸로 조회해 개인에게 도달할 수는 없습니다. 찾을 만한 방문자별 행이 없기 때문입니다. 집계는 세는 순간에 일어나며, 저장된 기록에 대한 나중의 보고 단계로 일어나지 않습니다. 합계가 날짜별로 초기화되는 것도 같은 이유입니다. 영원히 누적되고 충분히 곱게 썰린 카운터는 축적을 통해 조용히 지문 데이터베이스가 될 것이고, 설계는 그 표류를 나중에 사과하는 대신 미리 거부합니다.

두 가지 추가 선택은 이 글을 결코 읽지 않을 사람들을 보호합니다. Global Privacy Control 신호를 보내는 브라우저는 전혀 세어지지 않습니다. 그 신호는 «나를 추적하지 마»라는 뜻이며, 가장 존중하는 해석은 그것들을 신중하게 세는 것이 아니라 그 실행들을 완전히 제외하는 것입니다. 그 외의 모든 사람에게는 페이지에 눈에 보이는 거부 옵션이 있으며, 어떤 세기가 일어나기 전에 존중됩니다. 그리고 45초 안에 끝나지 않는 실행은 «멈춤»으로, 자체 구간에서 한 번 세어집니다. 느림과 고장은 단일 집계 숫자 형태로 저희 운영자에게는 계속 보이되, 실패한 실행을 통해 어떤 개별 방문자도 따라가지 않습니다.

만들지 않기로 한 것들

설계에서 가장 교훈적인 부분은 빠진 것들의 목록입니다. 연결 수준의 탐지는 없습니다. TLS 지문도 없고, 핸드셰이크에 대한 JA3 방식의 읽기도 없습니다. 정직한 이유는 아키텍처에 있습니다. 이 사이트의 TLS는 그 앞에 서 있는 CDN에서 종료되므로, 저희 원본에서 가져온 핸드셰이크 읽기는 여러분의 브라우저보다 CDN의 협상과 설정을 훨씬 더 많이 설명하게 됩니다. 그것을 «여러분의 TLS 지문»으로 게시하는 것은 연극일 것입니다. 다른 사람의 이름이 붙은 그럴듯해 보이는 값 말입니다. 자신감 넘치지만 틀린 읽기를 하나 인쇄하는 프라이버시 도구는 사용자들에게 다른 모든 곳에서도 자신감 넘치지만 틀린 읽기를 믿도록 가르치는데, 이는 빈 패널보다 나쁩니다.

같은 규율이 나머지 생략들을 만들었습니다. 카운터가 거친 이유는 곱게 썰린 카운터가 축적을 통해, 한 번에 하나의 무해한 차원씩, 지문 데이터베이스가 되기 때문입니다. 마지막 방문에 대한 기억, 즉 «지난 실행 이후 이 값들이 바뀌었다»는 것은 여러분 자신의 브라우저 저장소 안에, 여러분의 기기에만 살며, 결코 전송되지 않습니다. 동기화되는 순간 그것은 기록이 될 것이고, 기록은 곧 데이터입니다. 정말로 유용했을 기능들이 잘려 나간 이유는 엔드포인트가 작게 유지된 이유와 같습니다. 데이터 비용이 도구의 전부인 목적일 때, 유용함은 변호가 되지 않습니다.

마지막으로, 남은 정직함의 각주입니다. 어떤 설계 글도 자기 찬사로 끝나서는 안 되기 때문입니다. 이 설계는 데이터를 최소화합니다. 읽기 자체를 덜 식별 가능하게 만들 수는 없습니다. 여러분의 GPU, 글꼴, 화면, 시간대는 누군가 저장하든 안 하든 거의 고유한 무언가로 결합됩니다. 그것이 바로 이 도구가 여러분에게 보여 주기 위해 존재하는 발견입니다. 데이터를 보관하지 않는 것은 저희로부터 여러분을 보호합니다. 기술 자체로부터 보호하지는 않으며, 그렇지 않은 척하는 것이 저희가 내놓을 수 있는 유일하게 진정으로 부정직한 기능일 것입니다.

출처와 추가 읽을거리

자주 묻는 질문

정말 아무것도 보관하지 않는지 확인할 수 있나요?

대부분은 그렇습니다. 그리고 확인하셔야 합니다. 브라우저의 네트워크 탭을 열고, 테스트를 실행하고, 무엇이 여러분의 기기를 떠나는지 지켜보세요. 로컬 읽기들은 대응하는 업로드 없이 렌더링되고, 유일한 요청은 이름이 적힌 세 개의 엔드포인트와 이름이 적힌 외부 서비스들이며, 이 글이 설명하는 좁은 값들을 운반합니다. 어떤 사이트에서든 «로그 없음»이라는 주장은 궁극적으로 여러분이 볼 수 없는 서버 동작에 기대고, 바로 그래서 설계는 전송되는 것을 최소화합니다. 여러분의 브라우저를 결코 떠나지 않는 것은 애초에 저희가 기록하거나, 팔거나, 유출할 수 없습니다.

왜 무언가를 세기까지 하나요?

희소성이 곧 교훈이기 때문입니다. 여러분의 신호 목록은 사이트가 무엇을 읽을 수 있는지를 알려 줍니다. «이 GPU는 오늘 4,000번의 실행 중 12번 나타났다»는 그 신호가 얼마나 식별 가능한지를 알려 주는데, 그것이 사소한 것과 위험 사이의 차이입니다. 세기는 그 맥락이 중요하기 때문에 유지되었고, 거친 값, 일일 합계, 세는 순간의 집계라는 형태로 다듬어져 그 맥락이 여러분에 대한 기록을 결코 필요로 하지 않도록 했습니다.

거부하면 지난 카운트가 삭제되나요? 그리고 Global Privacy Control이란 무엇인가요?

삭제할 방문자별 무언가는 없습니다. 카운트는 집계, 즉 값마다 하루에 숫자 하나이며, 여러분에게 붙은 행도, 식별자도, 방문 기록도 없습니다. 따라서 거부는 여러분의 향후 실행에 대한 세기를 멈추지만, 애초에 여러분과 연결된 적 없는 한 칸을 뺄 수는 없습니다. 그것이 시스템이 로그가 아니라 카운터로 구축된 이유입니다. Global Privacy Control(GPC)은 한 걸음 더 나아갑니다. 그것은 표준 신호, 즉 브라우저 설정이나 확장 프로그램으로, globalprivacycontrol.org에 설명되어 있으며, 모든 사이트에 «내 개인 정보를 팔거나 공유하지 마»라고 말합니다. 여러 브라우저가 이를 토글로 제공합니다. 이 테스트는 그것을 가장 강한 방식으로 존중합니다. GPC를 보내는 브라우저는 전혀 세어지지 않으며, 거부 클릭도 필요 없습니다.