헤드리스 브라우저 탐지: Playwright, Puppeteer 그리고 그 너머
Bot Detection 엔진은 신호 불일치, 누락된 API, 봇이 흉내 낼 수 없는 행동 패턴을 통해 15개 이상의 자동화 프레임워크를 식별합니다.
헤드리스 브라우저는 정교한 웹 스크래핑, credential stuffing, 그리고 사기 작업에서 선호되는 도구입니다. 단순한 HTTP 클라이언트와 달리 헤드리스 브라우저는 JavaScript를 실행하고, 페이지를 렌더링하며, 최신 웹 API를 지원합니다 — 그만큼 탐지하기가 훨씬 더 어렵습니다. Bot Detection 엔진은 여러 독립적인 탐지 방법을 사용해 15개 이상의 자동화 프레임워크를 거의 0에 가까운 오탐률로 식별합니다.
브라우저 자동화의 진화
브라우저 자동화는 단순한 curl 스크립트에서 크게 발전해 왔습니다. Playwright, Puppeteer, Selenium WebDriver 같은 최신 도구는 실제 브라우저 엔진 — Chromium, Firefox, WebKit — 을 헤드리스 모드로 제어합니다. 이들은 헤드 브라우저와 똑같이 JavaScript를 실행하고, CSS를 처리하며, canvas 요소를 렌더링하고, WebGL 쿼리를 처리합니다. 그래서 JavaScript 실행 능력만 단순히 확인하는 탐지 방법에는 보이지 않습니다.
최신 세대의 도구는 여기서 더 나아갔습니다. Playwright의 stealth 모드는 전통적인 bot detection이 의존하는 신호 상당수를 패치합니다. puppeteer-extra-plugin-stealth는 navigator 속성을 수정하고, WebGL 벤더 문자열을 재정의하며, 사용자 상호작용 이벤트를 위조합니다. 이러한 탐지 회피 조치는 봇 운영자와 탐지 시스템 사이의 군비 경쟁을 만들어냈습니다.
탐지 방법 1: WebDriver 플래그 분석
navigator.webdriver 속성은 브라우저가 자동화에 의해 제어될 때 true로 설정됩니다. 초기 탐지는 이 속성을 확인하는 것만큼이나 단순했습니다. 그러나 최신 stealth 도구는 이 속성을 삭제하거나 재정의합니다. 우리의 탐지는 더 깊이 들어갑니다 — 속성 값뿐 아니라 그 property descriptor, prototype chain 내 존재 여부, 그리고 재정의 시도가 있었는지까지 확인합니다. 또한 WebDriver 재정의에 수반되는 navigator.plugins 길이 이상 같은 관련 속성도 확인합니다.
탐지 방법 2: Chrome DevTools Protocol 아티팩트
Playwright와 Puppeteer는 Chrome DevTools Protocol(CDP)을 통해 브라우저를 제어합니다. stealth 모드가 활성화되어 있어도 CDP는 런타임에 아티팩트를 남깁니다: 특정 전역 변수, 수정된 getter 함수, 그리고 Window 및 Navigator 객체의 변경된 property descriptor 등입니다. 우리는 단순한 덮어쓰기에 견디는 기법으로 이러한 아티팩트를 탐침합니다.
탐지 방법 3: 헤드리스 브라우저 fingerprinting
헤드리스 Chrome은 헤드 Chrome과 다른 기능 집합을 가집니다. 특정 브라우저 플러그인이 없고, 일부 CSS 속성의 렌더링 특성이 다르며, 일부 MediaQuery 결과에 대해 다른 값을 보고합니다. 우리는 알려진 헤드리스 브라우저 특성의 데이터베이스를 유지하고, 들어오는 fingerprint를 이에 대조해 확인합니다.
주요 헤드리스 지표로는 다음이 있습니다: chrome.runtime 누락(헤드 Chrome에는 존재하지만 헤드리스에는 없음), 길이가 0인 navigator.plugins 배열, 이전 버전에서 헤드리스 모드와 연관된 특정 user agent 패턴, 그리고 헤드리스 Chrome이 iframe 보안 컨텍스트를 처리하는 방식의 차이 등입니다.
탐지 방법 4: Eval 길이 분석
JavaScript 엔진마다 내장 함수의 구현이 다르며, 이 구현들은 서로 다른 문자열 표현을 가집니다. Function.prototype.toString.call(eval)의 길이를 확인하고 이를 각 브라우저 엔진의 알려진 값과 비교함으로써, 환경 위장 — 예를 들어 헤드리스 Chrome 인스턴스가 Firefox인 척하는 경우 — 을 탐지할 수 있습니다.
탐지 방법 5: TLS 교차 검증
TLS fingerprinting 관련 글에서 논의했듯이, TLS Client Hello 메시지는 연결을 맺는 실제 브라우저 또는 HTTP 라이브러리를 드러냅니다. Playwright 스크립트가 Chrome을 제어할 때는 TLS fingerprint가 Chrome과 일치합니다 — 이는 예상되는 결과입니다. 그러나 커스텀 봇이 Python requests 라이브러리나 Go의 net/http를 사용할 경우, 어떤 user agent 문자열을 보내든 TLS fingerprint가 그 위장을 드러냅니다.
탐지 방법 6: 타이밍 및 행동 분석
실제 사용자는 상호작용 타이밍에서 자연스러운 변동을 보입니다. 마우스를 직선이 아닌 곡선으로 움직입니다. 클릭하기 전에 멈칫합니다. 가변적인 속도로 스크롤합니다. 자동화 도구는 사람의 행동을 시뮬레이션하는 것조차도 통계적으로 구별 가능한 패턴을 만들어냅니다 — 지나치게 일정한 타이밍, 완벽하게 직선인 마우스 경로, 부자연스러운 스크롤 속도 등입니다.
우리는 fingerprinting 과정 자체에서 최소한의 행동 신호를 수집합니다 — API 호출의 타이밍, 신호 수집의 순서, 특정 브라우저 API의 응답성 등입니다. 이러한 미세 행동 신호는 재정의 가능한 속성이 아니라 실제 실행 환경에 의존하기 때문에 자동화 도구가 위조하기 어렵습니다.
탐지 방법 7: 권한 및 API 불일치
실제 브라우저는 일관된 권한 상태와 API 가용성을 가집니다. 알림을 지원한다고 주장하면서 Notification 생성자가 없는 브라우저, 또는 특정 화면 해상도를 보고하면서 window.screen과 CSS media query에서 다른 값을 반환하는 브라우저는 변조 또는 에뮬레이션을 나타내는 불일치를 드러내고 있는 것입니다.
우리는 이러한 교차 검증 지점을 수십 개 확인하며, 자동화 도구가 관련된 모든 API에 걸친 일관성을 유지하지 않고 일부 신호만 선택적으로 재정의할 때 발생하는 모순을 찾아냅니다.
탐지 방법 8: VM 및 에뮬레이션 탐지
많은 봇 작업은 가상 머신이나 클라우드 인스턴스 안에서 실행됩니다. 이것만으로 자동화의 증거가 되지는 않지만, 다른 지표와 결합되면 강력한 신호가 됩니다. 여기서는 서로 다른 두 가지를 구분해 둘 필요가 있습니다 — 이 둘은 흔히 혼동되기 때문입니다.
첫째는 소프트웨어 렌더링입니다. 실제 GPU가 없는 머신은 소프트웨어 래스터라이저로 폴백하며, WebGL 렌더러 문자열이 이를 그대로 말해줍니다 — "llvmpipe", "SwiftShader"와 그 변형들이 이를 직접 지칭합니다. 이는 헤드리스 지표입니다: 렌더링 경로에 대해 알려주며, 모든 플랜에서 봇 판정에 반영됩니다.
둘째는 본래 의미의 가상 머신 탐지이며, 이는 Enterprise 플랜의 기능입니다. WebGL 렌더러와 벤더 문자열에서 하이퍼바이저 시그니처 — VMware, VirtualBox, Parallels, QEMU, Hyper-V — 를 읽어내고, 이를 소비자 기기와 맞지 않는 하드웨어 특성, 즉 VM 기본 화면 해상도, 데스크톱 User-Agent 뒤의 CPU 코어 1~2개, 2기가바이트 이하의 메모리와 교차 확인합니다. 어떤 단일 마커도 단독으로 결정하지 않습니다. 탐지기는 그 조합을 점수화하고, 발동한 마커와 함께 신뢰도 수치를 보고합니다. IP 인텔리전스에서 확인되는 데이터센터 및 호스팅 제공업체 주소 대역이 네트워크 쪽에서 이를 뒷받침합니다.
두 신호 모두 그 자체만으로는 자동화의 증거가 아닙니다 — 클라우드에서 호스팅되는 브라우저 테스트나 GPU 없는 가상 데스크톱은 정당한 사용입니다 — 그렇기 때문에 둘 다 단독으로 차단을 유발하는 대신 가중치가 부여된 판정에 반영됩니다.
다중 방법의 이점
각 탐지 방법은 개별적으로는 한계가 있습니다 — 정교한 봇 운영자는 어떤 단일 방법이든 우회할 수 있습니다. 그러나 모든 방법을 동시에 우회하면서 그 모두에 걸쳐 교차 검증의 일관성을 유지하는 것은 감당하기 어려울 정도로 비쌉니다. 모든 검사를 통과하는 봇을 개발하고 유지하는 비용은 대부분의 봇 작업이 지니는 경제적 가치를 초과합니다.
거의 0에 가까운 오탐
우리의 탐지는 reverse DNS로 검증된 검색 엔진 봇(Googlebot, Bingbot 등)에 대해서는 화이트리스트 모델로, 그 외 트래픽에 대해서는 다중 신호 모델로 작동합니다. 트래픽을 자동화된 것으로 분류하기 전에 여러 개의 상호 확증 신호를 요구합니다. 바로 그것이 보수적인 설계의 핵심입니다: 모호한 마커 하나만으로는 결코 충분하지 않으므로, 우연히 검사 하나에 걸린 평범한 방문자가 봇으로 분류되는 일은 없습니다.