Chromium 148부터 Math.tanh로 기반 OS를 식별할 수 있음
요약
Chromium 148부터 V8의 Math.tanh가 내장 라이브러리 대신 호스트 OS의 수학 함수를 호출하면서, 같은 입력 값이라도 Linux(glibc), macOS(libsystem_m), Windows(UCRT)에서 다른 비트 패턴을 반환하게 되었습니다. 이 차이를 이용해 한 번의 JavaScript 호출만으로 현재 실행 환경의 운영체제를 식별하는 것이 가능합니다.
핵심 포인트
- Math.tanh 함수를 통해 OS별 고유한 수학 라이브러리 서명을 얻을 수 있습니다.
- 호출 결과가 User-Agent와 다르면 위장(Spoofing)이 드러납니다.
- 정확한 탐지를 위해서는 ULP 차이를 고려해야 하며, CSS 삼각함수 등도 검사 대상입니다.
- 이 기법은 Chromium 148 버전부터 가능해진 변화를 이용합니다.
Chrome 148부터 V8의 Math.tanh가 내장 fdlibm 대신 호스트의 std::tanh를 호출하면서, 같은 입력도 Linux의 glibc·macOS의 libsystem_m·Windows의 UCRT에서 서로 다른 마지막 비트를 반환함
Math.tanh(0.8)은 Linux에서 0.6640367702678491, macOS에서 0.664036770267849, Windows에서 0.6640367702678489가 되어 한 번의 호출로 세 OS를 구분할 수 있으며, User-Agent가 주장하는 OS와 결과가 다르면 위장이 드러남
엔진마다 누출 경로가 달라 V8의 Math.*에서는 tanh만 호스트 수학 라이브러리를 사용하지만, Blink의 CSS 삼각함수 전체와 Web Audio 일부 연산도 OS별 라이브러리를 거침
값을 임의로 흔들면 실제 OS 어느 쪽과도 일치하지 않고 결정성까지 깨지므로, 대상 라이브러리의 계수·테이블·범위 축소·FMA 동작을 비트 단위로 재현하거나 원본 UCRT 코드를 직접 매핑해야 함
Scrapfly는 릴리스마다 871,000개 입력을 실제 Mac과 Chrome에 대조해 Math.tanh와 CSS 삼각함수 7개의 비트 일치를 검증하며, 정확도뿐 아니라 아키텍처 차이와 실행 시간도 실제 브라우저 수준으로 맞춤
Math.tanh가 드러내는 OS
Math.tanh(0.8)의 결과는 호스트 수학 라이브러리에 따라 달라짐
Linux Chrome의 glibc: 0.6640367702678491
macOS Chrome의 libsystem_m: 0.664036770267849
Windows Chrome의 UCRT: 0.6640367702678489
Apple과 glibc는 전체 입력의 약 4분의 1에서 대체로 1 ULP 차이를 보이며, Windows UCRT는 두 라이브러리와 몇 퍼센트의 입력에서 달라짐
ULP(unit in the last place)는 특정 크기에서 표현 가능한 연속 부동소수점 수 사이의 간격이며, 1 ULP는 double이 나타낼 수 있는 최소 차이임
실제 Chrome 150을 Linux, Apple Silicon 기반 macOS 26, Windows 11에서 DevTools Protocol로 측정하면 입력에 따라 분류력이 달라짐
tanh(0.5)는 세 OS 모두 0.46211715726000974로 같아 탐지에 쓸 수 없음
tanh(0.7)은 Linux만 1 ULP 차이남
tanh(0.8)은 세 OS가 모두 다르며 전체 범위는 2 ULP임
tanh(0.9)는 Windows만 1 ULP 차이남
약 4분의 3의 입력에서는 세 OS가 같은 결과를 내지만, 적절한 입력 하나면 OS별 서명을 얻을 수 있음
macOS를 주장하면서 Linux의 수학 비트를 반환하면 Math.tanh 결과가 User-Agent와 모순됨
Chrome 148에서 생긴 변화
Chrome 147까지 V8은 이식 가능한 수학 구현인 fdlibm 포트를 내장해 Math.tanh를 계산했으므로 모든 OS에서 같은 비트를 반환함
오른쪽 입력으로 tanh를 한 번 호출한 결과가 운영체제별 서명이 된다는 설명은 브라우저 버전 범위를 식별할 가능성을 놓쳤음
대부분은 User-Agent의 운영체제를 위조하지 않으며, 핑거프린팅은 운영체제 자체보다 준고유한 특성 조합에 관심을 둠. 발견은 흥미롭지만 글이 지나치게 LLM으로 작성돼 신뢰감을 떨어뜨림
이 글을 만든 회사는 실제로 Linux VM의 봇을 Windows나 macOS 물리 장비처럼 위장하려 함
그래야 봇 탐지를 더 쉽게 통과하고 다른 웹사이트에서 수집한 데이터를 고객에게 판매할 수 있음
지금 이 방법만으로는 Chromium 148 이상이라고만 판별할 수 있지만, 각 버전에서 추가된 V8·Blink 기능을 JavaScript나 CSS로 검사하면 약 120 버전 이후부터 주 버전을 확실히 특정할 수 있음
LLM으로 작성했다는 사실은 글과 블로그에 공개했으며 숨기거나 사람인 척한 것이 아님. 시간이 부족해 그렇지 않았다면 글을 아예 게시하지 못했을 것이고, 이 선택에 책임질 생각임
버전 범위를 식별할 수는 있지만 그런 수단은 이미 셀 수 없이 많음
브라우저는 계속 기능을 추가하고 버그를 수정하며, 그중 대부분을 JavaScript로 감지할 수 있음
내용이 사실이라면 누가 썼는지는 상관없으며, LLM의 핵심 논지도 타당함
모든 핑거프린팅 기법을 AI로 분석해 공개하고, 논란 끝에 브라우저가 이를 막도록 유도하면 자사 스크래핑 사업이 더 많은 돈을 벌 수 있으니 영리한 전략임
이런 회사들이 없었다면 브라우저 핑거프린팅이 지금처럼 만연하지 않았고 인터넷도 더 나았을 것임. 차라리 fingerprint.js처럼 이해관계가 명확한 반대편의 글을 선호함
스크래퍼가 있든 없든 인간을 추적하려면 핑거프린팅이 필요하며 결국 사용될 것이므로 동의하기 어려움
정확히 반올림되는 libm 함수는 훌륭하지만, 과거 glibc의 pow처럼 최악 성능이 끔찍해서는 안 됨
반올림 경계에 가까울 때 사용하는 고정밀 대체 경로를 직접 SLP 벡터화해 최악 성능을 개선해 볼 수 있지만, 이미 대부분의 용도에는 충분함. JavaScript 엔진이 ECMAScript 명세에서 권장하는 fdlibm을 계속 쓰지 않는 점은 의외이며, Math.tanh가 JavaScript의 병목 경로라면 상당히 특이한 코드임
왜 고정 정밀도와 정수 연산이 더 널리 쓰이지 않는지 이해하기 어려움
공학에서는 훨씬 단순한 하드웨어에서 동작하고 오차를 수학적으로 쉽게 모델링할 수 있어 고정소수점을 자주 사용했음. IEEE 754 부동소수점은 이론적으로도 미심쩍으며, 정밀도 손실에서는 가수보다 작은 정수, 즉 24비트 미만 정수가 32비트 부동소수점보다 나을 때도 있음
최근 몇 달간 HN 활동이 뜸했는데, 커뮤니티가 콘텐츠를 저질로 낙인찍고 LLM 사용을 탐지하는 데 편집증적으로 집착하는 듯함
Tor Browser와 Mullvad Browser도 결국 운영체제 은폐를 포기했지만, 어쩌면 그러지 말았어야 함
그만큼 핑거프린팅 경로가 지나치게 많아 보임
운영체제 숨기기가 가능한지도 불분명하므로 올바른 결정이었다고 봄
브라우저 안팎에서 운영체제별 동작 차이가 너무 많이 발생해 모두 처리하기 어려움. 캔버스 추출을 차단하거나 잡음을 넣어도 렌더링 차이가 노출될 수 있으며, Tor Browser 개발자도 완전히 다른 운영체제는커녕 X11과 Wayland의 차이조차 숨길 수 없다고 확인했음. https://forum.torproject.org/t/linux-is-it-alright-to-run-th...
Tor Browser는 navigator.platform조차 수정하지 않으므로 Windows가 아닌 환경을 알아내기가 매우 쉬움
선호하는 JavaScript 주입 플러그인으로 다음 코드를 넣으면 됨: let oldTanh = Math.tanh; Math.tanh = x => oldTanh(x) + Math.random()/10000000;
더 간결하게 Math.tanh = Math.random;을 선호함
글에서 이미 다루고 있으니 “No noise”를 검색하면 됨
여러 봇 방지 업체가 이 교체를 탐지해 핑거프린팅 신호로 활용할 것임
이제 정상값 대신 핑거프린트를 숨기는 사용자로 드러나 오히려 더 식별하기 쉬워질 수 있음
최신 glibc는 CORE-MATH의 정확히 반올림되는 tanh 를 사용하므로 글에 인용된 값과 다른 결과를 반환함
다른 초월함수도 합리적인 성능으로 정확한 반올림을 구현할 수 있는지는 아직 불분명해 각 함수가 저마다 고유한 핑거프린트를 남김
Chrome은 실행 코드만 수백 MB라 사용자 공간 라이브러리의 절반쯤은 정적 링크했을 줄 알았음
또한 tanh는 함수 호출이 아니라 JavaScript JIT가 CPU 명령으로 내보내는 내장 연산이라고 생각했는데, 수학 연산을 위해 dlsym() 함수로 분기해야 한다는 점이 이상함. CPU 명령 자체도 핑거프린팅될 수는 있음
x87 FPU는 초월함수를 마이크로코드로 구현했지만 대부분의 명령어 집합은 이를 제공하지 않음
마이크로코드는 분기 예측 같은 이점을 얻지 못해 실제로 소프트웨어 구현보다 느림
기억하기로 Chrome은 JIT되지 않은 모드에서 NaN 값의 사용되지 않는 비트를 보존하는 유일한 브라우저이며, 코드가 JIT되면 그 비트가 0으로 바뀜
이 싸움에서 이길 수 있는지 의문임
충분히 많은 함수를 실행하면 실행 시간 비율과 반올림 결과를 조합해 운영체제와 정확한 기종은 물론, 같은 장비에서 실행 중인 다른 작업까지 추정할 수 있을 듯함. 완전히 막기보다는 조금 어렵게 만드는 정도만 가능해 보임
결국 사회와 법이 따라잡아야 함. 문 잠금장치가 침입을 완전히 막지 못해도 사회적 비난과 형사 처벌이 보완하듯, 이런 방식의 개인 추적을 불법화하고 그 이익을 사용하는 회사와 취업자를 사회적으로 배척해야 함
사이버 공간에서는 불법이거나 불법이어야 할 행위를 하는 이들이 집행 불가능한 관할권에 있는 경우가 많음
러시아·미얀마·북한 같은 곳에서는 법치가 작동하지 않고, 외국인을 속이는 범죄자를 현지 당국이 적극적으로 보호하기도 하므로 문 잠금장치 비유가 성립하지 않음
AI 자동 생성 콘텐츠
본 콘텐츠는 RSS: GeekNews (한국어)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기