Phát hiện headless browser: Playwright, Puppeteer và hơn thế nữa
Engine Bot Detection của chúng tôi nhận diện hơn 15 framework tự động hóa thông qua tín hiệu mâu thuẫn, API thiếu và mẫu hành vi mà bot không thể giả mạo.
Headless browser là vũ khí ưa thích cho việc web scraping tinh vi, credential stuffing và các chiến dịch gian lận. Khác với HTTP client đơn giản, headless browser thực thi JavaScript, render trang và hỗ trợ các web API hiện đại — khiến chúng khó bị phát hiện hơn nhiều. Engine Bot Detection của chúng tôi dùng nhiều phương pháp phát hiện độc lập để nhận diện hơn 15 framework tự động hóa với gần như không có false positive.
Sự tiến hóa của tự động hóa trình duyệt
Tự động hóa trình duyệt đã đi một chặng đường dài từ những script curl đơn giản. Các công cụ hiện đại như Playwright, Puppeteer và Selenium WebDriver điều khiển engine trình duyệt thật — Chromium, Firefox hay WebKit — ở chế độ headless. Chúng thực thi JavaScript, xử lý CSS, render phần tử canvas và xử lý truy vấn WebGL y hệt trình duyệt có giao diện. Điều này khiến chúng vô hình trước các phương pháp phát hiện chỉ đơn thuần kiểm tra khả năng thực thi JavaScript.
Thế hệ công cụ mới nhất còn đi xa hơn. Chế độ stealth của Playwright vá nhiều tín hiệu mà bot detection truyền thống dựa vào. Puppeteer-extra-plugin-stealth chỉnh sửa thuộc tính navigator, ghi đè chuỗi vendor của WebGL và làm giả sự kiện tương tác của người dùng. Những biện pháp chống phát hiện này đã tạo ra một cuộc chạy đua vũ trang giữa người vận hành bot và các hệ thống phát hiện.
Phương pháp phát hiện 1: Phân tích cờ WebDriver
Thuộc tính navigator.webdriver được đặt thành true khi trình duyệt bị điều khiển bởi tự động hóa. Trước đây, việc phát hiện đơn giản chỉ là kiểm tra thuộc tính này. Nhưng công cụ stealth hiện đại xóa hoặc ghi đè nó. Cách phát hiện của chúng tôi đi sâu hơn — chúng tôi kiểm tra không chỉ giá trị thuộc tính mà cả property descriptor của nó, sự hiện diện của nó trong prototype chain, và liệu đã có nỗ lực định nghĩa lại nó hay chưa. Chúng tôi cũng kiểm tra các thuộc tính liên quan như bất thường về độ dài của navigator.plugins vốn đi kèm với việc ghi đè WebDriver.
Phương pháp phát hiện 2: Artifact của Chrome DevTools Protocol
Playwright và Puppeteer điều khiển trình duyệt thông qua Chrome DevTools Protocol (CDP). Ngay cả khi chế độ stealth đang hoạt động, CDP vẫn để lại artifact trong runtime: các biến global cụ thể, hàm getter bị chỉnh sửa và property descriptor bị thay đổi trên đối tượng Window và Navigator. Chúng tôi dò tìm các artifact này bằng những kỹ thuật vững vàng trước những lần ghi đè đơn giản.
Phương pháp phát hiện 3: Fingerprinting headless browser
Chrome headless có tập năng lực khác với Chrome có giao diện. Nó thiếu một số plugin trình duyệt, có đặc tính render khác nhau đối với vài thuộc tính CSS, và báo cáo giá trị khác nhau cho một số kết quả MediaQuery. Chúng tôi duy trì một cơ sở dữ liệu về các đặc tính đã biết của headless browser và đối chiếu fingerprint đến với nó.
Các chỉ dấu headless quan trọng bao gồm: thiếu chrome.runtime (có ở Chrome giao diện nhưng vắng ở headless), mảng navigator.plugins có độ dài bằng không, các mẫu user agent cụ thể từng gắn với chế độ headless ở các phiên bản trước, và khác biệt trong cách Chrome headless xử lý context bảo mật của iframe.
Phương pháp phát hiện 4: Phân tích độ dài eval
Các engine JavaScript khác nhau có cách hiện thực khác nhau cho các hàm dựng sẵn, và những cách hiện thực đó có biểu diễn chuỗi khác nhau. Bằng cách kiểm tra độ dài của Function.prototype.toString.call(eval) và so sánh với giá trị đã biết cho từng engine trình duyệt, chúng tôi có thể phát hiện việc giả mạo môi trường — ví dụ, một instance Chrome headless đang giả vờ là Firefox.
Phương pháp phát hiện 5: Kiểm tra chéo TLS
Như đã bàn trong bài viết về TLS fingerprinting, thông điệp TLS Client Hello tiết lộ trình duyệt hay thư viện HTTP thực sự đang tạo kết nối. Khi một script Playwright điều khiển Chrome, TLS fingerprint khớp với Chrome — điều này là dự kiến. Nhưng khi một bot tùy biến dùng thư viện requests của Python hay net/http của Go, TLS fingerprint phơi bày sự lừa dối bất kể chuỗi user agent nào được gửi đi.
Phương pháp phát hiện 6: Phân tích thời gian và hành vi
Người dùng thật thể hiện sự biến thiên tự nhiên trong nhịp tương tác. Họ di chuyển chuột theo đường cong, không phải đường thẳng. Họ dừng lại trước khi nhấp. Họ cuộn ở tốc độ thay đổi. Các công cụ tự động, ngay cả những công cụ mô phỏng hành vi con người, cũng tạo ra những mẫu có thể phân biệt được về mặt thống kê — nhịp thời gian quá nhất quán, đường đi chuột thẳng hoàn hảo, và vận tốc cuộn không tự nhiên.
Chúng tôi thu thập tín hiệu hành vi tối thiểu ngay trong quá trình fingerprinting — thời điểm của các lệnh gọi API, thứ tự thu thập tín hiệu, và độ phản hồi của một số browser API. Những tín hiệu vi hành vi này khó để công cụ tự động giả mạo vì chúng phụ thuộc vào môi trường thực thi thực tế, chứ không phải vào các thuộc tính có thể ghi đè.
Phương pháp phát hiện 7: Mâu thuẫn về quyền và API
Trình duyệt thật có trạng thái quyền và mức độ khả dụng API nhất quán. Một trình duyệt tuyên bố hỗ trợ notification nhưng không có constructor Notification, hoặc báo cáo một độ phân giải màn hình cụ thể nhưng lại trả về giá trị khác từ window.screen và CSS media query, đang thể hiện những mâu thuẫn cho thấy có sự can thiệp hoặc mô phỏng.
Chúng tôi kiểm tra hàng chục điểm kiểm tra chéo như vậy, tìm những mâu thuẫn nảy sinh khi công cụ tự động ghi đè có chọn lọc một số tín hiệu mà không duy trì tính nhất quán trên tất cả các API liên quan.
Phương pháp phát hiện 8: Phát hiện máy ảo và mô phỏng
Nhiều chiến dịch bot chạy bên trong máy ảo hoặc cloud instance. Bản thân điều này không phải bằng chứng của tự động hóa, nhưng là một tín hiệu mạnh khi kết hợp với các chỉ dấu khác. Chúng tôi phát hiện máy ảo qua chuỗi renderer WebGL chứa từ khóa gắn với máy ảo (như "llvmpipe" hay "SwiftShader"), đặc tính phần cứng không phù hợp với thiết bị người dùng phổ thông (đúng 2 nhân CPU và 2GB bộ nhớ — mặc định phổ biến của máy ảo), và các dải IP đã biết của nhà cung cấp cloud.
Lợi thế đa phương pháp
Mỗi phương pháp phát hiện riêng lẻ đều có hạn chế — một người vận hành bot tinh vi có thể né được bất kỳ phương pháp đơn lẻ nào. Nhưng né tất cả phương pháp cùng lúc, trong khi vẫn duy trì tính nhất quán của kiểm tra chéo trên toàn bộ, thì tốn kém đến mức không thể chấp nhận. Chi phí phát triển và duy trì một bot vượt qua mọi kiểm tra vượt quá giá trị kinh tế của hầu hết các chiến dịch bot.
Gần như không có false positive
Cơ chế phát hiện của chúng tôi vận hành theo mô hình danh sách trắng cho bot của công cụ tìm kiếm (Googlebot, Bingbot, v.v.) được xác minh qua reverse DNS, và mô hình đa tín hiệu cho lưu lượng khác. Chúng tôi yêu cầu nhiều tín hiệu bổ trợ trước khi phân loại lưu lượng là tự động. Cách tiếp cận thận trọng này đảm bảo tỷ lệ false positive dưới 0,1% — được xác minh trên hàng tỷ sự kiện production.