수학 함수 하나가 운영체제를 웹사이트에 leaked(누출)하고 있다

수학 함수 하나가 운영체제를 웹사이트에 leaked(누출)하고 있다

브라우저 지문프라이버시보안Chromium운영체제V8

데이터 소스:HN + web research · HN

2026년 7월 12일, 안티스크레이핑 기술 회사 Scrapfly의 엔지니어가 기술 블로그 한 편을 발표하며 불안한 발견 하나를 드러냈다. Chrome 148부터, 아무 해도 없어 보이는 수학 함수 Math.tanh()가 운영체제에 따라 약간 다른 결과를 반환한다는 것이다. 다시 말해, 어떤 웹사이트든 당신에게 수학 계산 한 줄만 돌리게 하면, 당신이 Windows, macOS, Linux 중 무엇을 쓰는지 판단할 수 있다.

Scrapfly 블로그 스크린샷: 운영체제별 Math.tanh 반환값 차이 ▲ 이미지 출처: Scrapfly 블로그 글 스크린샷

이 발견은 당일 Hacker News 메인 페이지에 올랐고, 207개의 추천과 90개의 토론을 얻었다. 개발자 커뮤니티의 반응은 “놀라움”이라는 한 단어로 요약할 수 있다. 다들 브라우저 지문이 Canvas 그리기, WebGL 렌더링, 오디오 처리 같은 “중화기”를 통해 사용자를 추적하는 데는 익숙했지만, 평범한 쌍곡탄젠트 함수 하나가 운영체제 식별의 단서가 될 수 있다고는 아무도 생각하지 못했다.

똑같은 수학 문제, 세 개의 다른 답

구체적인 예로 설명해 보자. Chrome 150의 브라우저 콘솔에 Math.tanh(0.8), 즉 0.8의 쌍곡탄젠트 값을 입력하면, 서로 다른 운영체제의 실제 머신 세 대가 세 개의 다른 결과를 내놓았다.

운영체제Math.tanh(0.8)의 반환값
Linux (glibc)0.6640367702678491
macOS (libsystem_m)0.664036770267849
Windows (UCRT)0.6640367702678489

마지막 몇 자리 숫자에 주목하라. Linux는 macOS보다 한 자리 많고 값이 가장 크다. macOS는 Windows보다 한 자리 적고 중간이다. Windows의 값은 약간 작다. 세 값의 차이는 마지막 한두 자리에만 있어 육안으로는 거의 알아챌 수 없다. 하지만 컴퓨터에게는 이 차이가 명확한 운영체제 서명을 구성하기에 충분하다.

흥미로운 점은, 모든 입력이 차이를 만들지는 않는다는 것이다. Scrapfly의 테스트 데이터에 따르면, 약 4분의 3의 입력값은 세 시스템에서 결과가 완전히 일치한다. 예를 들어 Math.tanh(0.5)는 Linux, macOS, Windows 모두 0.46211715726000974를 반환한다. 반면 tanh(0.7)은 Linux의 값만 나머지 둘과 다르고, tanh(0.9)는 Windows만 독보적이다. tanh(0.8)은 마침 세 시스템을 모두 구별해내는 “스위트 스폿”이다.

Scrapfly 비교 표: 입력값별 세 시스템의 tanh 반환값 ▲ 이미지 출처: Scrapfly 블로그 비교 표 스크린샷

이는 추적자가 복잡한 조작을 할 필요가 없음을 뜻한다. 웹 페이지에서 Math.tanh()를 몇 번 돌리고, 핵심 입력값 몇 개를 골라 반환 결과를 비교하면, 방문자의 운영체제를 추론할 수 있다. 만약 방문자의 User-Agent가 자신이 macOS를 쓴다고 주장하는데 tanh의 반환값은 전형적인 Linux 결과라면—이 방문자는 십중팔구 신분을 위장하고 있는 것이다.

누구의 책임인가? 버그인가, 수학의 숙명인가?

여기까지 읽은 독자는 이렇게 물을지도 모른다. 이것은 Chrome의 버그인가?

답은 다소 미묘하다. 완전히 버그는 아니지만, 한 번의 “수선”이 가져온 뜻밖의 부작용이다.

Chrome 148 이전에는, V8 엔진(Chrome의 JavaScript 실행 코어)이 Math.tanh를 구현할 때 자체 번들된 수학 라이브러리 fdlibm을 사용했다. 모든 플랫폼에서 같은 코드를 쓰기 때문에, 사용자가 Windows든 macOS든 Linux든 Chrome에서 Math.tanh의 결과는 완전히 일치했다. 당연히 어떤 운영체제 정보도 누출하지 않았다.

하지만 2025년 말, V8 팀은 코드 변경(commit c1486295ae5)을 커밋하여 Math.tanh의 구현을 자체 fdlibm에서 C++ 표준 라이브러리의 std::tanh로 교체했다. 이 변경의 동기는 매우 합리적이다. V8 자체의 코드 크기를 줄이고, 운영체제 저수준에서 이미 고도로 최적화된 수학 라이브러리를 활용하며, 이론적으로 성능도 향상시킬 수 있다는 것이다. 이 변경은 V8 14.8.57과 함께 배포됐고, Chrome 148에 대응한다.

문제는, 서로 다른 운영체제 저수준의 수학 라이브러리(Linux의 glibc, macOS의 libsystem_m, Windows의 UCRT)가 쌍곡탄젠트 함수를 구현하는 방식이 서로 다르다는 데 있다.

이것은 수학적으로 근본적인 제약이다. IEEE 754 표준은 부동소수점의 저장 형식과 기본 연산(사칙연산, 제곱근)의 정밀도 요구 사항을 규정하지만, 삼각함수, 지수함수, 쌍곡함수 같은 “초월 함수”에 대해서는 “올바른 반올림”—즉 계산 결과를 마지막 이진 자릿수까지 정확하게 보장하는 것—을 강제하지 않는다. 이유는 매우 실용적이다. 올바른 반올림을 구현하는 연산량이 극도로 크고, 성능에 심각한 영향을 미치기 때문이다. 그래서 각 운영체제의 수학 라이브러리는 자기만의 근사 알고리즘, 계수표, 상수를 갖고 있으며, 이들의 목표는 속도를 보장하는 전제하에 오차를 “최소 정밀도 단위”(ULP) 이내로 제어하는 것이다.

그래서 Chrome 148 이후 Math.tanh가 운영체제에 따라 보이는 미세한 차이는, 본질적으로 수학 근사 알고리즘의 다양성이 드러난 것이다. 이것은 간단히 “고칠” 수 있는 버그가 아니다. 사실 이는 부동소수점 연산 분야에서 수십 년간 존재해 온 트레이드오프—속도 대 정밀도—다. 다만 이 트레이드오프가 브라우저라는 사용자 인터페이스 계층에 노출되자, 뜻밖에도 프라이버시 누출의 통로가 되어 버린 것이다.

tanh만이 아니다—브라우저 전체를 관통하는 누출면

더 경계해야 할 것은, Math.tanh가 빙산의 일각에 불과하다는 점이다.

Scrapfly의 블로그는, 호스트 운영체제의 수학 라이브러리(libm)를 통해 계산하는 모든 브라우저 API가 이론적으로 같은 누출 위험을 안고 있다고 지적한다. 여기에는 CSS의 삼각함수(sin(), cos(), tan() 등)와 Web Audio API의 다이내믹 컴프레서가 포함된다. 이 기능들은 모두 저수준 운영체제의 수학 라이브러리에 의존해 부동소수점 계산을 수행한다.

바꿔 말하면, 설령 Chrome 팀이 Math.tanh를 고친다 해도, 브라우저에 호스트 운영체제의 수학 함수를 호출하면서 통일된 처리를 하지 않는 API가 하나라도 남아 있는 한, 지문 식별의 창은 여전히 존재한다.

이것은 전형적인 “두더지 잡기”식 군비 경쟁이다. 브라우저 개발자는 사용자 신분을 누출할 수 있는 모든 틈을 막으려 애쓰고, 추적자와 안티스크레이핑 시스템은 끊임없이 새로운 신호를 찾는다. 지문 식별의 역사는 곧 양측이 끊임없이 새로운 전장을 발견해 온 역사다. Canvas에서 WebGL로, 폰트 목록에서 오디오 파형으로, 그리고 이제는 수학 함수 결과의 차이로. 개발자가 구멍 하나를 막을 때마다, 추적자는 도저히 단서가 될 수 없어 보이는 다음 지표를 찾아낸다.

HN 커뮤니티의 양극화된 반응

HN의 토론은 두 개의 전혀 다른 관점을 보여줬다.

일부 개발자는 이 발견이 일반 사용자에게 미치는 실질적 영향이 제한적이라고 본다. 사용자 “Aurornis”는, 대다수 사용자가 자신의 User-Agent를 위조하지 않기 때문에 tanh로 운영체제를 식별하는 것이 추적자에게 추가 정보를 주지 않는다고 지적했다. User-Agent 자체가 이미 당신이 어떤 운영체제를 쓰는지 웹사이트에 알려주고 있기 때문이다. 그는 이 취약점이 브라우저 버전 범위의 지문 식별에는 더 의미가 있지만, 그렇다 해도 수많은 지문 신호 중 작은 퍼즐 조각에 불과하다고 봤다.

다른 일부의 관점은 완전히 다르다. 사용자 “jeroenhd”는, 이 발견이 Scrapfly 같은 안티스크레이핑 회사에 중요한 이유가 바로 그들이 스크레이퍼 프로그램을 진짜 브라우저처럼 위장시켜야 하기 때문이라고 지적했다. Linux 가상 머신에서 돌아가는 스크레이퍼가 자신이 macOS의 Chrome이라고 주장하는데 tanh의 반환값이 진짜 운영체제를 배신한다면, 안티스크레이핑 시스템은 이것이 봇임을 쉽게 식별할 수 있다.

필자는 양쪽 다 일리가 있다고 본다. 평범하고 정직한 브라우저 사용자에게 Math.tanh의 누출은 확실히 사족이다. 당신의 User-Agent가 이미 어떤 시스템을 쓰는지 웹사이트에 능동적으로 알려주고 있으니까. 하지만 신분을 숨기려는 사용자(프라이버시 보호 목적이든, 데이터 스크레이핑 목적이든)에게 이 새로 발견된 신호는 이런 의미다. User-Agent를 위장하는 것만으로는 부족하고, 수학 함수의 반환값까지 위장해야 한다는 것.

이는 더 깊은 질문을 끌어낸다. 인터넷 아키텍처 안에서, 우리가 “중립적”이고 “표준화된” 인프라라고 여기는 것들 중 얼마나 많은 것이 실제로는 우리 기기에 관한 독특한 신호를 소리 없이 전달하고 있는가? 수학 함수 하나, CSS 한 줄, 오디오 처리 한 대목—이것들은 본래 신분의 단서가 되어선 안 되지만, 저수준 구현의 다양성 때문에 사실상의 추적 식별자가 되어 버렸다.

앞으로 무슨 일이 벌어질까?

현재 이 누출 통로는 Chrome 148, 149, 150에 영향을 미친다. Chrome 팀은 아직 이 문제에 대해 공개적으로 응답하지 않았다. Scrapfly 팀은, 이 누출 통로를 완전히 닫으려면 브라우저가 모든 계층(V8, Blink, Web Audio)에서 통일된 수학 라이브러리를 쓰거나, 최소한 출력을 “평탄화” 처리해야 한다고 밝혔다. 하지만 이렇게 하면 성능 손실이 따를 수 있고, 호환성과 유지보수 측면에서도 만만치 않은 도전이 있다.

일반 사용자에게 필자는 이렇게 말하고 싶다. 공황에 빠질 필요는 없다. 이 발견은 프라이버시 연구 분야의 흥미롭지만 긴급하지는 않은 새 신호일 뿐, 당신의 계정이 탈취되게 할 심각한 보안 취약점이 아니다. 그럼에도 주목할 가치가 있는 이유는, 그것이 하나의 추세를 대변하기 때문이다. 사용자의 디지털 발자국은 점점 더 완전히 숨기기 어려워지고 있다.

이 이야기의 진짜 의미는 어쩌면 더 보편적인 관찰을 드러낸다는 데 있다. 소프트웨어 시스템의 복잡한 의존 사슬 속에서, 겉보기엔 하찮아 보이는 저수준의 선택 하나가 상위 계층에서 예상치 못한 프라이버시 결과를 낳을 수 있다는 것이다. Chrome 팀의 한 번의 코드 정리는 본래 중복을 줄이고 성능을 높이기 위한 것이었지만, 뜻밖에 운영체제 식별을 위한 새 창을 열어 버렸다. 이런 의미에서 Math.tanh의 이야기는 “의도와 부작용”에 관한 전형적인 사례다.

참고 링크:

  • Scrapfly: Browser Math OS Fingerprint
  • HN 토론 (item?id=48884853)