CreepJS không chỉ đọc một giá trị bị giả mạo — nó đối chiếu nguồn tin cậy và không tin cậy để tìm mâu thuẫn mà hầu hết công cụ giả mạo không giấu nổi.
Hầu hết công cụ lấy dấu vân tay chỉ trả lời một câu hỏi: trình duyệt này độc đáo đến mức nào? CreepJS, một dự án nghiên cứu vân tay mã nguồn mở, đặt ra một câu hỏi khác: trình duyệt này có đang nói thật không? Thay vì chỉ thu thập một hash Canvas hay một chuỗi renderer WebGL rồi dừng lại, nó đối chiếu chéo từng tín hiệu với mọi tín hiệu khác mà cùng trình duyệt đó phát ra — và với cách một triển khai thật của tín hiệu đó lẽ ra phải hoạt động. Khi một giá trị tự nó trông hợp lý nhưng lại mâu thuẫn với điều gì đó khác mà trình duyệt tiết lộ, CreepJS gọi đó là một lời nói dối, và điểm tin cậy của nó giảm tương ứng. Bài viết này giải thích mô hình phát hiện nói dối đó ở mức tổng quát: nguồn "tin cậy" và "không tin cậy" nghĩa là gì, việc can thiệp vào prototype hay getter tự tố cáo bản thân như thế nào, và tại sao cùng một loại kiểm tra lại vạch trần cả trình duyệt anti-detect lẫn việc giả mạo user-agent ngây thơ.
Điểm Chính
- Ý tưởng cốt lõi của CreepJS là tính nhất quán, không phải danh tính: nó không cần một cơ sở dữ liệu các giá trị "đúng", chỉ cần bằng chứng rằng các tín hiệu của chính trình duyệt mâu thuẫn với nhau hoặc mâu thuẫn với cách một triển khai thật sự hoạt động.
- Nó so sánh nguồn tin cậy và nguồn không tin cậy cho cùng một sự thật — đọc trực tiếp một thuộc tính so với suy ra nó một cách gián tiếp, hoặc so sánh kết quả trên main thread với cùng phép tính đó chạy trong một Worker — và gắn cờ khi chúng bất đồng.
- Việc can thiệp vào prototype và getter — cách chuẩn mực mà các công cụ giả mạo dùng để ghi đè giá trị như
navigator.userAgenthayHTMLCanvasElement.prototype.toDataURL— để lại bằng chứng cấu trúc: mô tả thuộc tính (property descriptor) bị thay đổi, đầu ra.toString()không còn khớp với mã native, và tính đồng nhất tham chiếu (reference identity) thay đổi qua các lần gọi. - Các bẫy Proxy dùng để chặn truy cập thuộc tính tự chúng cũng có thể bị phát hiện, vì một API trình duyệt thật không cần một lớp bọc
Proxyđể trả lời truy vấn. - Chính logic phát hiện nói dối đó là lý do vì sao việc giả mạo user-agent hay Canvas ngây thơ — và ngay cả trình duyệt anti-detect được xây dựng kỹ lưỡng — vẫn có xu hướng để lại một khuôn mẫu mâu thuẫn thay vì một dấu hiệu lộ liễu duy nhất.
CreepJS Thực Sự Kiểm Tra Điều Gì
Theo kho GitHub của chính nó, mục đích công bố của CreepJS là "làm sáng tỏ những điểm yếu và rò rỉ quyền riêng tư trong các tiện ích mở rộng và trình duyệt chống lấy dấu vân tay hiện đại." Nó chạy một loạt kiểm tra rộng — dựng hình canvas và WebGL, khả năng âm thanh và font, computed style của CSS, dữ liệu màn hình và múi giờ, đặc điểm runtime JavaScript, và nhiều hơn nữa — và thay vì chỉ băm kết quả thành một định danh duy nhất, nó đánh giá tính hợp lý nội tại của từng tín hiệu. Đầu ra là một điểm tin cậy kèm theo bảng phân tích chi tiết: tín hiệu nào trông là native, và tín hiệu nào trông như được lắp ghép, bị vá, hoặc theo cách nào đó không nhất quán với một phiên bản trình duyệt thật.
Cách đóng khung đó quan trọng với bất kỳ ai đang tự kiểm tra thiết lập của mình. Một công cụ đo tính độc đáo của vân tay cho bạn biết bạn dễ bị nhận diện đến mức nào. Một công cụ phát hiện nói dối cho bạn biết liệu danh tính bạn đang trình bày có thực sự đứng vững hay không — điều này gần với những gì các hệ thống giảm thiểu bot, chấm điểm gian lận và phát hiện trình duyệt anti-detect kiểm tra trong thực tế sản xuất, như đã trình bày trong cách website phát hiện trình duyệt anti-detect và giả mạo vân tay.
Mô Hình Phát Hiện Nói Dối: Tính Nhất Quán, Không Phải Danh Tính
Một kiểm tra vân tay ngây thơ đọc một giá trị rồi ghi lại nó. Một kiểm tra phát hiện nói dối đọc cùng một sự thật qua nhiều hơn một đường dẫn rồi so sánh các câu trả lời. Nếu một trình duyệt thực sự đúng như nó tuyên bố, mọi đường dẫn tới cùng một sự thật đều phải đồng ý với nhau, vì tất cả cuối cùng đều bắt nguồn từ cùng một engine, cùng một pipeline dựng hình, và cùng một hệ điều hành. Nếu có gì đó đã bị vá để trình bày một giá trị sai, rất khó để vá mọi đường dẫn một cách nhất quán — và những đường dẫn bị bỏ sót chính là nơi lời nói dối lộ ra.
Đây là cùng nguyên tắc đằng sau kiểm tra tính nhất quán vân tay nói chung: tính độc đáo đo lường một vân tay hiếm đến mức nào, còn tính mạch lạc (coherence) đo lường liệu nó có thể hợp lý thuộc về một thiết bị thật hay không. CreepJS áp dụng ý tưởng mạch lạc đó ở mức chi tiết hơn — không chỉ "GPU có khớp với hệ điều hành được khai báo không" mà còn "hành vi cấp thấp của API cụ thể này có khớp với những gì một triển khai thật của API đó tạo ra không," lặp lại qua hàng chục kiểm tra riêng lẻ.
Nguồn Tin Cậy So Với Không Tin Cậy: Nơi Những Lời Nói Dối Bị Bắt
Một cách hữu ích để nghĩ về loại công cụ này là theo khái niệm nguồn tin cậy và không tin cậy cho cùng một sự thật nền tảng. Một nguồn tin cậy là nguồn tốn kém hoặc khó khăn để một script giả mạo chặn lại — một giá trị được đọc từ một execution context khác, được tính toán như một tác dụng phụ của đoạn mã không liên quan, hoặc được suy ra từ hành vi thay vì từ một thuộc tính mà script có thể đơn giản gán lại. Một nguồn không tin cậy là chính thuộc tính hiển nhiên, thường bị giả mạo — navigator.userAgent, một lệnh gọi Canvas toDataURL(), một tham số WebGL — những thứ mà mọi công cụ anti-detect và tiện ích riêng tư đều đã biết cách chặn.
Kiểm tra không phải là "giá trị không tin cậy này có thật không" một cách riêng lẻ; mà là "giá trị không tin cậy có khớp với giá trị tin cậy hay không." Một vài ví dụ về hình dạng chung của kiểm tra này:
- Main thread so với ngữ cảnh Worker. Cùng một phép tính — một lệnh vẽ Canvas, một lần đọc múi giờ, một phép toán — có thể chạy cả trên main thread lẫn bên trong một Web Worker. Một trình duyệt thật tạo ra cùng kết quả ở cả hai nơi, vì cả hai execution context đều dùng chung một engine nền tảng. Các công cụ giả mạo thường chỉ vá đối tượng global của main thread mà bỏ sót global scope riêng của Worker, khiến hai ngữ cảnh bất đồng với nhau. Kiểm tra tính nhất quán Canvas xuyên ngữ cảnh — so sánh đầu ra
OffscreenCanvastrong một Worker với một canvas gắn vào tài liệu — là một trường hợp cụ thể của khuôn mẫu chung này. - Đọc trực tiếp so với giá trị suy ra. Một số sự thật có thể được đọc trực tiếp từ một thuộc tính và cũng có thể được suy luận gián tiếp — từ một tác dụng phụ, một thông báo lỗi, hoặc một đoạn hành vi mà chỉ một triển khai thật mới tạo ra đúng. Nếu giá trị đọc trực tiếp và giá trị suy ra bất đồng, chỉ một trong hai có thể đang nói thật, và hiếm khi đó là cái dễ vá.
- Danh tính được khai báo so với hành vi quan sát được. Một chuỗi user-agent tuyên bố một trình duyệt và engine; thời gian thực thi của JavaScript engine, cách diễn đạt thông báo lỗi, và sự hiện diện của các tính năng tiết lộ engine nào thực sự đang chạy, bất kể chuỗi đó nói gì — đúng cơ chế được giải thích trong cách phát hiện giả mạo user-agent.
Không kiểm tra nào trong số này yêu cầu CreepJS biết vân tay "đúng" của bạn lẽ ra phải là gì. Nó chỉ cần hai cửa sổ độc lập nhìn vào cùng một sự thật, và niềm tin rằng một trình duyệt thật không thể không cho ra cùng một câu trả lời qua cả hai cửa sổ đó.
Mô Tả Thuộc Tính, Getter và Bẫy Proxy
Bên cạnh việc so sánh chéo nguồn, phương pháp luận của CreepJS còn bao gồm phát hiện can thiệp prototype trực tiếp — tìm bằng chứng cấu trúc cho thấy một API trình duyệt đã bị ghi đè, thay vì chỉ kiểm tra xem giá trị trả về của nó có trông hợp lý hay không.
Giả mạo một giá trị như navigator.userAgent hay một phương thức Canvas thường có nghĩa là định nghĩa lại một getter hoặc gán lại một phương thức prototype. Sự can thiệp đó làm thay đổi nhiều thứ ngoài chính giá trị đó:
- Mô tả thuộc tính (property descriptor).
Object.getOwnPropertyDescriptor()gọi trên một phương thức native trả về một hình dạng cụ thể, có thể dự đoán được, và một.toString()dạng"function name() { [native code] }". Một phiên bản bị vá ngây thơ thường trả về thân hàm hiển thị thay vào đó, hoặc một bản ghi đè quên tổng hợp marker native-code. - Bẫy Proxy. Chặn truy cập thuộc tính bằng một
Proxylà cách phổ biến để vá getter một cách động, nhưng một Proxy đang hoạt động lại phản ứng khác với một thuộc tính native dưới các kiểm tra bằng nhau theo tham chiếu — truy cập nó hai lần có thể trả về các thực thể wrapper có thể phân biệt được, hoặc các bẫyget/hascủa nó phản hồi những phép dò mà một thuộc tính native không bao giờ cần trả lời. - Tính đồng nhất tham chiếu (reference identity). Một phương thức prototype thật là chính xác cùng một đối tượng hàm mỗi lần được truy cập. Một phiên bản bị vá được triển khai như một closure mới hoặc một wrapper được sinh ra có thể không vượt qua phép so sánh
===qua các lần truy cập lặp lại — điều mà một triển khai native không bao giờ gặp phải.
Không điều nào trong số này chứng minh giá trị thật lẽ ra phải là gì — chỉ chứng minh rằng thuộc tính đang trả lời truy vấn không phải là thuộc tính mà trình duyệt vốn có sẵn. Đó thường là tín hiệu mạnh hơn nhiều so với việc cố đoán xem một hash Canvas hay chuỗi GPU cụ thể "có trông đúng không," vì nó hoàn toàn không phụ thuộc vào một cơ sở dữ liệu các giá trị đã biết là đúng.
Vì Sao Giả Mạo Ngây Thơ và Trình Duyệt Anti-Detect Vẫn Thất Bại
Chủ đề lặp lại xuyên suốt tất cả các kiểm tra này là: giả mạo một tín hiệu thì dễ, còn giả mạo một cách nhất quán toàn bộ tập hợp mạch lạc các nguồn tin cậy và không tin cậy thì không hề dễ. Một script ghi đè navigator.userAgent hiếm khi cũng vá phiên bản tương đương trong ngữ cảnh Worker, điều chỉnh mọi mô tả thuộc tính xuôi dòng, và tái tạo đầu ra .toString() dạng mã native cho chính getter nó vừa cài vào. Trình duyệt anti-detect — các nhánh Chromium được xây dựng chuyên biệt để phối hợp các giá trị giả mạo trên toàn bộ hồ sơ — tiến gần hơn, nhưng ngay cả chúng cũng có xu hướng để lại cùng một loại đường nối: một giá trị được vá trên main thread nhưng không được vá bên trong Worker, một bẫy Proxy phản hồi hơi khác một chút so với thuộc tính native, hoặc một danh tính được tuyên bố mà một kiểm tra nguồn tin cậy âm thầm phủ nhận.
Điều này mang tính lâu bền: các kiểm tra cụ thể mà một công cụ nghiên cứu vân tay chạy sẽ tiếp tục mở rộng khi engine và kỹ thuật giả mạo phát triển, nhưng mô hình nền tảng — đọc cùng một sự thật qua một đường dẫn tin cậy và một đường dẫn không tin cậy, rồi coi sự bất đồng là bằng chứng — không bao giờ lỗi thời. Đó cũng chính là lý do khiến việc phát hiện dựa trên tính mạch lạc bền vững trước các mánh khóe đơn lẻ: một bộ phát hiện không cần liệt kê mọi lời nói dối có thể xảy ra, mà chỉ cần liên tục nhân lên số lượng đường dẫn độc lập mà một công cụ giả mạo phải vá giống hệt nhau.
Kiểm Tra Trình Duyệt Của Chính Bạn
Các công cụ của chính BrowserInsight áp dụng cùng lối tư duy ưu tiên tính nhất quán này, mà không đòi hỏi bạn phải diễn giải một dashboard vân tay cấp nghiên cứu. Kiểm tra vân tay hiển thị các tín hiệu Canvas, WebGL và font của bạn cùng với các kiểm tra mạch lạc gắn cờ khi chúng không khớp nhau; công cụ phát hiện bot chạy các kiểm tra tập trung vào tự động hóa và tính nhất quán mà một hệ thống giảm thiểu sẽ chạy trong môi trường sản xuất. Nếu bạn muốn một phiên bản từng bước của cùng bài tự kiểm tra này, Tính nhất quán vân tay trình duyệt: Danh sách tự kiểm tra trình bày bảy kiểm tra cụ thể về UA/GPU/múi giờ/font mà bạn có thể chạy trong vài phút. Không điều nào trong bài này là hướng dẫn để qua mặt CreepJS hay bất kỳ công cụ phát hiện nói dối nào khác — mục đích của việc hiểu mô hình này là để thấy tại sao tính mạch lạc, chứ không phải bất kỳ giá trị đơn lẻ nào, mới thực sự là thứ bị kiểm tra.
Câu hỏi thường gặp
CreepJS có thu thập hay lưu trữ vân tay của tôi không?
CreepJS là một công cụ nghiên cứu chạy phía client mà bạn tự chạy trên trình duyệt của mình để xem nó tiết lộ gì về bạn; mục đích của việc tự chạy nó là để kiểm tra tín hiệu của chính bạn, chứ không phải để bị nó theo dõi. Luôn kiểm tra chính sách quyền riêng tư của một công cụ trước khi tin tưởng vào bất kỳ dịch vụ lấy dấu vân tay được lưu trữ (hosted) nào.
Một trình duyệt anti-detect được xây dựng tốt có thể qua mặt một công cụ phát hiện nói dối như CreepJS không?
Đối với một tập con các kiểm tra, đôi khi có thể. Việc phối hợp nhất quán mọi nguồn tin cậy và không tin cậy — main thread và ngữ cảnh Worker, mọi mô tả thuộc tính, mọi tác dụng phụ suy ra — trên một tập kiểm tra liên tục phát triển là điều rất khó duy trì, đó là lý do các thiết lập anti-detect có xu hướng để lại ít nhất một đường nối dù được xây dựng cẩn thận, như đã bàn trong cách website phát hiện trình duyệt anti-detect và giả mạo vân tay.
Điểm tin cậy thấp có phải là bằng chứng người dùng thật là bot hay kẻ gian lận không?
Không. Điểm phát hiện nói dối đo lường tính mạch lạc của vân tay, không đo lường ý định. Tiện ích riêng tư, bản trình duyệt cũ hơn, và các cấu hình bất thường nhưng hợp pháp đều có thể làm vấp một số kiểm tra riêng lẻ. Các hệ thống sản xuất kết hợp tín hiệu này với các tín hiệu khác thay vì coi nó là một phán quyết độc lập.
Phát hiện nói dối khác gì với kiểm tra tính độc đáo vân tay thông thường?
Kiểm tra tính độc đáo (Cover Your Tracks của EFF là một ví dụ nổi tiếng) đo lường vân tay tổng hợp của bạn dễ nhận diện đến mức nào giữa những khách truy cập khác. Phát hiện nói dối thay vào đó hỏi liệu các tín hiệu riêng lẻ tạo nên vân tay đó có nhất quán nội tại với nhau và với hành vi trình duyệt thật hay không — một câu hỏi khác hoàn toàn không đòi hỏi phải so sánh bạn với vân tay của bất kỳ ai khác.

