Cách website phân biệt điện thoại thật với instance Android thuê: chuỗi GPU renderer, thiếu cảm biến, phần cứng đồng nhất, thiếu attestation web dự phòng.
Một "cloud phone" là một instance Android thật (hoặc ảo hóa) chạy trên máy chủ từ xa, được điều khiển qua màn hình streaming hoặc một API từ xa thay vì một thiết bị cầm trên tay bạn. Được thuê theo phút, khởi tạo hàng loạt lên tới hàng nghìn instance, và có thể reset về trạng thái sạch theo yêu cầu, chúng đã trở thành lựa chọn thay thế mới hơn cho việc giả mạo dấu vân tay trình duyệt desktop — yêu cầu trông như đến từ một chiếc điện thoại di động thật, vì về mặt kỹ thuật, một lớp nào đó của nó đúng là như vậy. Phát hiện chúng không phải là bắt một lời nói dối trong chuỗi user-agent; mà là đặt câu hỏi liệu mọi thứ mà trình duyệt di động báo cáo có nhất quán nội tại với một chiếc điện thoại vật lý thật hay không. Hướng dẫn này đề cập đến những tín hiệu trả lời câu hỏi đó.
Điểm chính
- Các instance Android cloud và giả lập (emulated) thường không thể tạo ra một GPU thật. Trong khi điện thoại vật lý báo cáo
Adreno,Mali, hoặcPowerVRtừWEBGL_debug_renderer_info, một instance ảo hóa báo cáo một renderer phần mềm hoặc passthrough nhưSwiftShader,llvmpipe, hoặcvirtio-gpu. - Điện thoại thật phơi bày dữ liệu gia tốc kế và con quay hồi chuyển với nhiễu hiệu chuẩn (calibration noise) đặc trưng cho từng thiết bị, ngay cả khi đặt yên trên bàn; một cloud instance không có chip vật lý nào đứng sau các sensor API đó và hoặc không phơi bày gì cả, hoặc phơi bày một giá trị hằng định đáng ngờ.
- Một instance đi thuê đơn lẻ chỉ là một khách truy cập di động. Nhưng hàng nghìn "người dùng khác nhau" cùng báo cáo
hardwareConcurrency,deviceMemoryvà độ phân giải màn hình giống hệt nhau thì đó là sự tương quan ở quy mô farm, không phải trùng hợp ngẫu nhiên. - Ứng dụng Android gốc (native) có thể yêu cầu một phán quyết Play Integrity được bảo chứng bằng phần cứng mà một cloud instance khó lòng tạo ra; web mở không có gì tương đương, đó chính xác là lý do vì sao việc phát hiện phía trình duyệt phải quay về các kiểm tra tính nhất quán trong hướng dẫn này.
- Bạn có thể xem chuỗi trình kết xuất GPU, mức độ phơi bày cảm biến và giá trị hardware-concurrency của chính thiết bị mình bằng kiểm tra vân tay của BrowserInsight.
Từ hồ sơ desktop đến các instance Android đi thuê
Các công cụ giả mạo dấu vân tay đã tập trung nhiều năm vào trình duyệt desktop: đổi user-agent, vá hash canvas, chèn một chuỗi GPU nghe có vẻ hợp lý, và hy vọng các mảnh ghép ăn khớp với nhau. Việc phát hiện đã bắt kịp — phát hiện trình duyệt anti-detect giờ đây thường xuyên bắt được chính xác loại hồ sơ desktop chắp vá đó bằng cách kiểm tra xem các tín hiệu của nó có nhất quán với nhau hay không. Một cloud phone né tránh cuộc đối đầu đó theo cách khác: thay vì giả mạo dấu vân tay di động từ một máy desktop, nó chạy một ngăn xếp (stack) Android thật (hoặc ảo hóa) ở đâu đó trong một trung tâm dữ liệu và trình bày trình duyệt thật, không giả mạo của phiên đó như "thiết bị". User-agent không phải là một lời nói dối. Cái thiếu chính là mọi thứ mà một chiếc điện thoại vật lý mang theo mà một tủ rack máy chủ thì không: một chip GPU, phần cứng chuyển động, và sự đa dạng phần cứng tự nhiên của một điện thoại cho mỗi người dùng.
Đó chính là câu hỏi lâu dài mà bài viết này trả lời — không phải nhà cung cấp nào cho thuê các instance này, cũng không phải làm sao để một farm trông đáng tin, mà là cách một website, từ bên trong một phiên trình duyệt, phân biệt được thiết bị di động đứng sau một yêu cầu là điện thoại vật lý hay chỉ là một bản thế thân ảo hóa.
Tín hiệu 1: Chuỗi trình kết xuất GPU
Mọi GPU di động đều là một chip vật lý có tên, và cái tên đó xuất hiện trong extension WEBGL_debug_renderer_info của WebGL giống hệt như trên desktop — xem những tổ hợp dấu vân tay bất khả thi để biết chuỗi renderer gắn chặt với phần cứng bên dưới nó đến mức nào. Một điện thoại Android thật báo cáo một chuỗi vendor thuộc một trong số ít các họ GPU di động:
const gl = document.createElement('canvas').getContext('webgl');
const dbg = gl.getExtension('WEBGL_debug_renderer_info');
gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL);
// Điện thoại thật: "Adreno (TM) 740" hoặc "Mali-G715-Immortalis" hoặc "PowerVR Rogue GE8320"
// Cloud instance: "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero)), SwiftShader driver)"
// Android giả lập: "llvmpipe (LLVM 15.0.7, 256 bits)" hoặc một chuỗi passthrough virtio-gpu
SwiftShader, llvmpipe, và virtio-gpu đều là các renderer phần mềm hoặc thuộc lớp ảo hóa — chúng tồn tại chính xác vì máy đang chạy trình duyệt không có GPU di động chuyên dụng nào để giao việc kết xuất cho. Một instance Android chạy trên máy chủ hoặc rơi về một trong các renderer này, hoặc chuyển tiếp một chuỗi GPU của máy chủ thuộc về một card NVIDIA hay AMD cấp desktop — bản thân điều đó cũng là một dấu hiệu tố cáo: không có chiếc điện thoại nào trên thế giới xuất xưởng với chip NVIDIA GeForce. Dù theo cách nào, chuỗi renderer cũng nêu tên phần cứng mà một chiếc điện thoại thật không thể chứa.
Có một lưu ý khiến tín hiệu này chưa đủ để kết luận một mình: không phải instance Android lưu trữ nào cũng chạy trên phần cứng máy chủ x86. Một số nhà cung cấp dựng đội máy của họ trên bo mạch máy chủ ARM, số khác đơn giản là gắn hàng loạt điện thoại thật vào rack trong trung tâm dữ liệu rồi mở truy cập từ xa — và những instance như vậy hoàn toàn có thể báo cáo một chuỗi Adreno hay Mali thật một trăm phần trăm, bởi đúng là có một GPU di động thật đang kết xuất. Suy luận chỉ đúng theo một chiều: renderer phần mềm hoặc renderer của lớp ảo hóa là bằng chứng mạnh cho một ngăn xếp ảo hóa, còn một renderer di động nghe hợp lý thì không chứng minh được rằng phía sau phiên đó là một chiếc điện thoại vật lý nằm trong tay ai đó. Chính sự bất đối xứng này khiến các tín hiệu bên dưới mới là thứ gánh phần nặng, mỗi khi chuỗi GPU trông sạch sẽ.
Tín hiệu 2: Cảm biến chuyển động không tồn tại
Điện thoại thật mang gia tốc kế và con quay hồi chuyển, và — như đã đề cập trong lấy dấu vân tay cảm biến thiết bị — các chip đó để lại một chữ ký hiệu chuẩn ổn định, đặc trưng cho từng thiết bị trong các số đọc của chúng, ngay cả khi điện thoại nằm yên bất động. Một instance cloud hay giả lập không có chip nào như vậy ở bất kỳ đâu trong chuỗi phần cứng của nó. Đọc API DeviceMotionEvent hoặc dựng một đối tượng Accelerometer từ họ Sensor API trên một trong các instance này thường để lộ một trong hai dấu hiệu. Hoặc là số đọc không bao giờ thực sự đến: trình lắng nghe devicemotion không hề kích hoạt, hoặc có kích hoạt nhưng mọi trường gia tốc đều là null, hoặc việc khởi tạo một đối tượng Accelerometer báo lỗi vì nền tảng không hề ghi nhận có cảm biến nào như vậy. Hoặc là lớp giả lập chèn vào các giá trị tổng hợp, và khi đó số đọc trở về sạch sẽ đến mức đáng ngờ: một giá trị hằng định, không có chút trôi (drift) nhỏ theo từng trục mà dung sai sản xuất của một chip thật tạo ra. Sàn nhiễu (noise floor) của một điện thoại vật lý không bao giờ phẳng lì tuyệt đối; còn một giá trị mặc định gán cứng trong script thì thường là như vậy.
Tín hiệu 3: Tính đồng nhất phần cứng ở quy mô farm
Bất kỳ một phiên cloud phone đơn lẻ nào, khi kiểm tra tách biệt, đều có thể trông hợp lý — chính mẫu hình lặp lại trên nhiều phiên mới tố cáo một device farm. Một quần thể khách truy cập di động thật mang tính đa dạng phần cứng tự nhiên: các chipset khác nhau báo cáo số lõi hardwareConcurrency khác nhau, các bậc deviceMemory khác nhau, và một dải rải rác các độ phân giải màn hình trải khắp nhiều thế hệ điện thoại. Một device farm cấp phát nhiều instance từ cùng một số ít image máy ảo, nên hàng trăm hoặc hàng nghìn phiên tự xưng là những người dùng khác nhau lại hội tụ về cùng một số lõi, cùng bậc bộ nhớ, cùng kích thước màn hình, và cùng chuỗi trình kết xuất GPU giống hệt nhau cùng một lúc. Xét riêng lẻ thì không phiên nào là bất khả thi cả — chính sự tương quan giữa các phiên mới là thứ mà một hệ thống phát hiện chấm điểm, cùng kiểu lập luận ở cấp độ tổng hợp mà phát hiện bot theo hành vi áp dụng cho các mẫu hình tương tác thay vì các thuộc tính thiết bị tĩnh.
Tín hiệu 4: Tính tự nhất quán của cảm ứng, con trỏ và viewport
Tín hiệu cảm ứng và viewport của một điện thoại thật vốn dĩ khớp với nhau: navigator.maxTouchPoints báo cáo một giá trị khác 0, đặc tính CSS media (pointer: coarse) khớp, và kích thước viewport nằm trong phạm vi của một màn hình thực tế đã xuất xưởng với một device-pixel-ratio hợp lý. Hạ tầng cloud phone streaming một màn hình từ xa hoặc phơi bày một trình duyệt qua API điều khiển từ xa có thể lệch ở bất kỳ điểm nào trong số này: một lớp điều khiển bằng chuột đưa vào các sự kiện chạm tổng hợp, một viewport được resize để vừa với cửa sổ streaming thay vì kích thước vật lý của một màn hình thật, hoặc một device-pixel-ratio không tương ứng với bất kỳ chiếc điện thoại nào thực sự được bán ra. Không cái nào trong số này tự nó là bằng chứng buộc tội — một cửa sổ trình duyệt bị resize cũng có thể trông bất thường trên một điện thoại thật — nhưng khi chồng lên một chuỗi GPU không khớp và cảm biến vắng mặt, nó góp thêm vào cùng một bức tranh.
Vì sao web không có phương án attestation dự phòng
Ứng dụng Android gốc có một công cụ mạnh hơn nhiều: device attestation. Một ứng dụng có thể gọi Play Integrity API của Google và nhận về một phán quyết được bảo chứng bằng phần cứng — được ký bởi một môi trường thực thi tin cậy (trusted execution environment) — khẳng định rằng thiết bị và ứng dụng là chính hãng và không bị chỉnh sửa, thay vì suy luận điều đó từ một đống tín hiệu có thể giả mạo. Bản cập nhật của Google về khả năng phát hiện mối đe dọa của Play Integrity mô tả phán quyết deviceIntegrity như một câu trả lời cho câu hỏi: ứng dụng có đang chạy trên một thiết bị Android chính hãng, được chứng nhận Play Protect hay không — một ngưỡng mà một cloud instance đi thuê nhìn chung không vượt qua được, vì phía sau nó không có khóa được bảo chứng bằng phần cứng của một thiết bị thật, và do đó cũng không có token attestation hợp lệ.
Web mở không có gì tương đương. Đề xuất Web Environment Integrity API của Google — đối tác phía trình duyệt của Play Integrity — đã bị rút lại trước khi ra mắt, nên hiện tại không có trình duyệt nào phơi bày một token attestation cho website. Đó chính xác là lý do vì sao việc phát hiện cloud phone ở phía trình duyệt phải quay về các kiểm tra tính nhất quán nêu trên: không có bằng chứng mật mã để kiểm tra, một website chỉ còn cách suy luận "điện thoại thật hay bản thế thân ảo hóa" từ việc GPU, cảm biến, hồ sơ phần cứng và tín hiệu cảm ứng có khớp với nhau theo cách mà một chiếc điện thoại chính hãng sẽ có hay không.
| Tín hiệu | Điện thoại thật | Instance cloud / giả lập |
|---|---|---|
| Chuỗi trình kết xuất GPU | Chuỗi vendor Adreno, Mali, PowerVR | SwiftShader, llvmpipe, virtio-gpu, hoặc chuỗi NVIDIA/AMD cấp desktop |
| Cảm biến chuyển động | Số đọc thời gian thực với nhiễu hiệu chuẩn riêng của từng thiết bị | Vắng mặt, ném lỗi, hoặc một giá trị tổng hợp hằng định đáng ngờ |
| Hồ sơ phần cứng qua các phiên | Số lõi, bậc bộ nhớ, kích thước màn hình đa dạng tự nhiên | Nhiều phiên hội tụ về cùng các giá trị giống hệt nhau |
| Cảm ứng / viewport | Điểm chạm khác 0, con trỏ coarse, viewport của thiết bị thật | Loại con trỏ không khớp, viewport hoặc pixel ratio không chuẩn |
| Attestation (chỉ ứng dụng gốc) | Token Play Integrity / App Attest hợp lệ | Thất bại hoặc không thể tạo token |
Vị trí của chủ đề này trong các tín hiệu liên quan
Hướng dẫn này nói riêng về việc phân biệt một phiên Android ảo hóa với một phiên thật — nó có giao thoa với, nhưng không đồng nhất với, vài chủ đề lân cận. Lấy dấu vân tay trình duyệt di động đề cập đến tập tín hiệu rộng hơn mà bất kỳ điện thoại nào cũng phơi bày, dù thật hay không. Những tổ hợp dấu vân tay bất khả thi đề cập đến các mâu thuẫn GPU/hệ điều hành/font cấp desktop, một kiểm tra liên quan nhưng khác biệt. Device attestation đề cập đến bằng chứng mật mã của ứng dụng gốc mà web không có. Và phát hiện trình duyệt anti-detect đề cập đến việc giả mạo dấu vân tay desktop chứ không phải hạ tầng di động đi thuê. Phát hiện cloud phone nằm ở giao điểm: các tín hiệu di động, được kiểm tra tính nhất quán nội tại và giữa các phiên, trong bối cảnh không có attestation nào để dựa vào.
Kiểm tra tín hiệu của chính bạn
Kiểm tra vân tay của BrowserInsight báo cáo chuỗi trình kết xuất GPU thực tế, mức độ phơi bày cảm biến chuyển động, hardwareConcurrency và deviceMemory của thiết bị bạn — đúng những thuộc tính mà hướng dẫn này đã đi qua. Chạy nó từ một chiếc điện thoại thật so với một trình duyệt bên trong một phiên Android từ xa hoặc ảo hóa sẽ khiến khoảng cách giữa hai bên hiện ra ngay lập tức.
Câu hỏi thường gặp
Cloud phone có giống với một trình giả lập di động không?
Không hẳn, dù các website thường không thể phân biệt được hai thứ này từ phía trình duyệt. Một cloud phone thường stream hoặc proxy một hệ thống Android thật (hoặc ảo hóa) chạy trên phần cứng máy chủ từ xa; còn một trình giả lập di động chạy hoàn toàn trên một máy desktop, mô phỏng Android mà không có bất kỳ phần nào thực sự là di động về mặt vật lý. Cả hai thường thiếu một GPU di động thật và cảm biến chuyển động, đó là lý do vì sao chúng kích hoạt cùng những tín hiệu phát hiện được đề cập ở đây.
Nhà cung cấp cloud phone có thể giả mạo một chuỗi trình kết xuất GPU thật không?
Có thể báo cáo một chuỗi như vậy, nhưng đầu ra pixel thực tế của một bài kiểm tra kết xuất WebGL vẫn đến từ bất kỳ phần cứng nào thực sự đang chạy bên dưới — cùng sự bất đối xứng khiến việc giả mạo GPU có thể bị phát hiện trên desktop. Một chuỗi renderer được khai báo mà không khớp với đầu ra kết xuất, hoặc mô tả một chip có đặc điểm thuộc họ GPU không nhất quán với phần còn lại của dấu vân tay, tự bản thân nó đã là một dấu hiệu tố cáo.
Có phải mọi hệ thống phát hiện đều kiểm tra cảm biến chuyển động không?
Không — quyền truy cập cảm biến phải được yêu cầu hoặc bị chặn bởi cơ chế cấp quyền trong nhiều ngữ cảnh, nên không phải mọi hệ thống phát hiện đều đọc nó ở mỗi lượt truy cập. Ở nơi nào cảm biến khả dụng, đó là một tín hiệu có độ tin cậy cao, chính vì giả mạo nhiễu hiệu chuẩn một cách thuyết phục khó hơn nhiều so với giả mạo một thuộc tính tĩnh như chuỗi user-agent.
Vì sao web không có thứ gì đó giống Play Integrity?
Google từng đề xuất một phiên bản tương đương cho trình duyệt, Web Environment Integrity, nhưng đã rút lại trước khi ra mắt, sau khi vấp phải phản đối từ các nhà cung cấp trình duyệt và những người ủng hộ quyền riêng tư về rủi ro "gác cổng" khi để các website từ chối những trình duyệt không có attestation. Các app store gốc thực thi Play Integrity và App Attest ở cấp nền tảng theo cách mà web mở, do thiết kế, không làm được.
Kết luận
Một cloud phone không cần phải nói dối về user-agent của nó để trông giống một khách truy cập di động — chạy một phiên trình duyệt di động thật vốn chính là toàn bộ ý tưởng của nó. Thứ nó không thể dễ dàng giả mạo là phần cứng bên dưới: chuỗi renderer của một chip GPU thật, nhiễu hiệu chuẩn cảm biến chuyển động theo thời gian thực, và sự đa dạng tự nhiên mà một quần thể điện thoại thuộc sở hữu cá nhân riêng lẻ tạo ra, thay vì một số ít image máy ảo được nhân bản. Vì web không có cơ chế attestation nguyên bản nào để dựa vào, phép kiểm tra tính nhất quán xuyên suốt GPU, cảm biến và hồ sơ phần cứng là tín hiệu mạnh nhất mà việc phát hiện phía trình duyệt có được, và đó cũng chính là logic "mọi thứ có khớp với mọi thứ khác không" bắt được các hồ sơ desktop bị giả mạo, chỉ là được áp dụng cho một tập tín hiệu khác, chỉ có ở di động.
Đọc thêm:
- Vân tay trình duyệt di động: Android và iOS bị theo dõi
- Lấy dấu vân tay cảm biến: gia tốc kế và con quay hồi chuyển
- Vân tay bất khả thi: Tổ hợp GPU/hệ điều hành/font khiến bạn bị lộ
- Xác thực thiết bị: Play Integrity và App Attest
- Cách Phát Hiện Trình Duyệt Anti-Detect và Giả Mạo Dấu Vân Tay
- Phát hiện bot theo hành vi: Chuyển động chuột phi tự nhiên


