Canvas fingerprinting vẽ một ảnh ẩn trong trình duyệt và biến khác biệt kết xuất nhỏ nhất thành mã định danh thiết bị ổn định. Cách nó hoạt động và cách chặn.
Canvas fingerprinting hoạt động bằng cách yêu cầu trình duyệt của bạn vẽ chữ và hình khối lên một canvas HTML5 vô hình, rồi đọc ngược lại các điểm ảnh kết quả và băm chúng thành một mã định danh ngắn, ổn định. Vì mỗi thiết bị kết xuất cùng những lệnh vẽ đó theo cách hơi khác nhau — tùy thuộc vào GPU, driver đồ họa, hệ điều hành và công cụ dựng phông chữ (font engine) — nên giá trị băm trở thành một chữ ký âm thầm đi theo bạn qua các trang web mà không cần bất kỳ cookie nào. Bài viết này đi xa hơn nhiều so với những điều cơ bản: các điểm ảnh thực sự khác biệt ra sao, canvas bổ sung bao nhiêu tính độc nhất, làm sao biết khi nào một trang web đang lấy dấu vân tay bạn, và vì sao một số biện pháp phòng vệ phổ biến lại có thể phản tác dụng.
Canvas Fingerprinting thực sự hoạt động như thế nào
Kỹ thuật này dựa vào phần tử <canvas>, vốn dùng để vẽ đồ họa bằng JavaScript. Một script theo dõi không bao giờ cần hiển thị canvas đó lên màn hình — nó tồn tại hoàn toàn trong bộ nhớ.
Quy trình gần như nhất quán trong hầu hết mọi triển khai:
- Tạo một canvas ngoài màn hình. Một canvas nhỏ (thường rộng 200–300 px) được tạo nhưng không bao giờ gắn hiển thị lên trang.
- Vẽ một cảnh cố định. Script kết xuất một chuỗi văn bản định sẵn — thường pha trộn nhiều phông chữ, màu sắc, một hai emoji và các hình chữ nhật chồng lên nhau. Emoji và Unicode bất thường được ưa dùng vì chúng buộc ngăn xếp phông chữ của hệ điều hành phải đưa ra quyết định kết xuất.
- Đọc ngược các điểm ảnh. Script gọi
toDataURL()để xuất canvas thành PNG Base64, hoặcgetImageData()để đọc mảng byte RGBA thô. Đây là hai đường đọc ngược duy nhất có ý nghĩa với việc lấy dấu vân tay — mọi script lấy dấu vân tay canvas, bất kể dùng thư viện nào, đều kết thúc bằng một lệnh gọi tới một trong hai hàm này. - Băm kết quả. Các byte đó được chạy qua một hàm băm (thường là kiểu FNV hoặc MurmurHash) để tạo ra một dấu vân tay gọn như
e3b0c44298fc1c14.
Điều khéo léo là các lệnh giống hệt nhau với tất cả mọi người, nhưng kết quả đầu ra thì không. Hai khách truy cập chạy cùng một script có thể tạo ra các giá trị băm khác nhau, còn cùng một khách truy cập lại tạo ra cùng một giá trị băm mỗi lần quay lại — đây chính xác là điều một kẻ theo dõi mong muốn.
Canvas không bao giờ được hiển thị. Bạn sẽ không thấy một cái nhấp nháy, một khung hình, hay bất kỳ dấu hiệu trực quan nào. Chính sự vô hình này là lý do canvas fingerprinting trở nên phổ biến đến vậy trong việc theo dõi thầm lặng.
Vì sao các điểm ảnh khác nhau giữa các thiết bị
Nếu việc vẽ chữ "Hello" lẽ ra phải cho kết quả tất định, vậy tại sao các byte lại thay đổi? Bởi mỗi tầng trong hệ thống của bạn đều đưa vào những sai lệch rất nhỏ nhưng có thể tái lập.
GPU và driver đồ họa
Khử răng cưa, kết xuất subpixel và cách tô đầy các đường cong đều được giao một phần cho GPU. Một chip tích hợp Intel, một GPU Apple Silicon và một card rời NVIDIA sẽ làm tròn các điểm ảnh ở rìa theo những cách khác nhau. Ngay cả hai máy có cùng mẫu GPU vẫn có thể khác biệt nếu phiên bản driver của chúng khác nhau.
Rasterize phông chữ
Yếu tố đóng góp lớn nhất chính là việc kết xuất văn bản. Công cụ dựng phông chữ của hệ điều hành — DirectWrite trên Windows, Core Text trên macOS, FreeType trên Linux — quyết định cách biến đường viền glyph thành điểm ảnh. Hinting, hiệu chỉnh gamma và thuật toán khử răng cưa cụ thể thay đổi theo nền tảng và phiên bản, nên các điểm ảnh xám dọc theo rìa chữ "g" mang một lượng thông tin phân biệt đáng ngạc nhiên.
Hệ điều hành và phông chữ đã cài
Việc phông chữ được yêu cầu có tồn tại hay không sẽ quyết định trình duyệt có phải thay thế bằng phông dự phòng hay không. Một emoji có thể được kết xuất thành đường viền phẳng trên hệ thống này và thành glyph đầy màu sắc trên hệ thống khác. Bộ emoji màu của hệ điều hành (Apple, Noto, Segoe) để lại một dấu vết đặc biệt mạnh.
Nhân trình duyệt và phiên bản
Chromium, Firefox và WebKit đều có triển khai canvas riêng. Quản lý màu và cách toDataURL() mã hóa dữ liệu PNG có thể thay đổi giữa các phiên bản trình duyệt, đó là lý do một bản cập nhật trình duyệt đôi khi làm thay đổi giá trị băm canvas của bạn.
Canvas bổ sung bao nhiêu tính độc nhất?
Canvas có giá trị với kẻ theo dõi không phải vì nó nhận diện riêng bạn, mà vì nó đóng góp một phần đáng kể entropy — thước đo mức độ một tín hiệu thu hẹp phạm vi bạn là ai. Trong các nghiên cứu về fingerprinting trong thực tế, canvas đã nhiều lần được xếp vào nhóm tín hiệu đơn lẻ có entropy cao nhất mà một trang web thụ động có thể đọc được, ngang với toàn bộ danh sách phông chữ đã cài. Bài kiểm tra công khai nổi tiếng nhất đo mức độ độc nhất này là Cover Your Tracks của EFF — dù điểm số của nó dễ bị hiểu sai hơn ta tưởng, điều mà chúng tôi phân tích trong Cover Your Tracks: điểm độc nhất không chứng minh điều gì.
Tuy vậy, canvas hiếm khi tự mình nhận diện được một người. Rất nhiều người dùng chung những cấu hình phổ biến — một chiếc laptop Windows nguyên bản chạy Chrome với phông chữ mặc định sẽ trùng với hàng triệu người khác. Sức mạnh thực sự của nó xuất hiện khi kết hợp: canvas cộng với WebGL, thông số màn hình, múi giờ và ngôn ngữ cùng nhau đẩy về một dấu vân tay gần như độc nhất. Để biết phần toán học thực sự đằng sau câu hỏi "cần bao nhiêu bit thì bạn trở nên độc nhất" và tập ẩn danh cuối cùng của bạn trông như thế nào, xem Entropy dấu vân tay trình duyệt và tập ẩn danh là gì.
Vì sao giá trị băm Canvas ổn định — cho đến khi nó không còn ổn định
Dấu vân tay canvas có một vòng đời khác thường khiến nhiều lời giải thích bị hiểu sai: giá trị băm ổn định qua các phiên truy cập nhưng không ổn định qua các thay đổi phần cứng hoặc phần mềm. Cả hai vế đều quan trọng, và việc gộp chung chúng lại là sai lầm phổ biến nhất khi mô tả kỹ thuật này.
Trên cùng một máy, giá trị băm hầu như không đổi. Cùng một GPU, cùng một bản driver, cùng một bộ rasterize phông chữ của hệ điều hành và cùng một phiên bản trình duyệt sẽ vẽ ra chính xác cùng những điểm ảnh mỗi lần — vì vậy kẻ theo dõi thấy cùng một giá trị ở lần ghé thăm đầu tiên lẫn lần thứ năm trăm, mà không cần bất kỳ cookie nào. Chính sự bền vững đó khiến canvas trở nên hữu ích như một mã định danh dài hạn ngay từ đầu.
Nhưng giá trị băm không phải vĩnh viễn. Nó thay đổi bất cứ khi nào một tầng nào đó trong chuỗi kết xuất thay đổi:
- Cập nhật driver GPU có thể làm lệch đi vài subpixel trong cách khử răng cưa hoặc cách làm tròn khi tô đầy đường cong — chỉ vậy là đủ để giá trị băm đổi khác.
- Nâng cấp hệ điều hành thường đi kèm một bộ rasterize phông chữ mới (một bản DirectWrite, Core Text hoặc FreeType mới), âm thầm thay đổi cách mỗi glyph được vẽ.
- Cập nhật trình duyệt có thể thay đổi cách
toDataURL()mã hóa dữ liệu PNG hoặc cách ngữ cảnh canvas 2D khử răng cưa, độc lập với hệ điều hành. - Đổi phần cứng (một laptop mới, một GPU khác) tạo ra một giá trị hoàn toàn khác, không có sự liên tục nào với giá trị cũ.
Trong thực tế, điều này có nghĩa là giá trị băm canvas suy giảm dần như một mã định danh theo từng tháng, chứ không phải từng ngày — hữu ích để theo dõi một phiên hoặc một lượt quay lại trong một cấu hình ổn định, nhưng không phải là dấu vân tay vĩnh viễn theo kiểu một số sê-ri phần cứng. Kẻ theo dõi bù đắp cho điều này bằng cách kết hợp canvas với các tín hiệu ổn định hơn thay vì chỉ dựa vào một mình nó, và đó chính xác là lý do vì sao việc chồng lớp entropy (xem liên kết về tập ẩn danh ở trên) quan trọng hơn bất kỳ tín hiệu đơn lẻ nào.
| Thuộc tính | Canvas Fingerprinting |
|---|---|
| Cần lưu trữ | Không (không cookie, không localStorage) |
| Sống sót qua việc xóa cache/cookie | Có |
| Sống sót qua chế độ ẩn danh/riêng tư | Thường là có |
| Người dùng nhìn thấy | Không |
| Mức đóng góp entropy điển hình | Cao trong các tín hiệu thụ động đơn lẻ |
| Bị vô hiệu khi xóa dữ liệu | Không |
| Bị vô hiệu khi đổi IP | Không |
Cách website sử dụng dấu vân tay Canvas
Canvas fingerprinting là con dao hai lưỡi. Cùng một cơ chế phục vụ cả mục đích xâm phạm lẫn bảo vệ:
- Theo dõi xuyên trang. Các mạng quảng cáo và phân tích nhúng trên nhiều trang đọc giá trị băm canvas để nhận ra một khách quay lại ngay cả sau khi đã xóa cookie, từ đó xây dựng hồ sơ hành vi.
- Chống gian lận và bảo mật tài khoản. Ngân hàng và đơn vị xử lý thanh toán đánh dấu các lần đăng nhập có dấu vân tay canvas đột nhiên khác với thiết bị đã biết, giúp phát hiện việc chiếm đoạt tài khoản.
- Phát hiện bot và lạm dụng. Trình duyệt headless và các framework tự động hóa thường tạo ra kết quả canvas hoặc quá đồng nhất hoặc kết xuất theo những cách dễ nhận biết, nên fingerprinting giúp tách người dùng thật khỏi lưu lượng do script tạo ra — xem Các kỹ thuật phát hiện bot để biết cách điều này hoạt động trong thực tế.
- Giới hạn tần suất và ngăn lạm dụng. Các dịch vụ dùng dấu vân tay làm khóa ổn định để chặn các tài khoản né giới hạn bằng cookie mới.
Cách phát hiện liệu bạn có đang bị lấy dấu vân tay Canvas
Bạn không thể thấy canvas, nhưng có thể để ý những hành vi đi kèm với nó.
Theo dõi các lệnh gọi API
Trong một nỗ lực lấy dấu vân tay, JavaScript gọi getContext('2d'), rồi fillText(), rồi toDataURL() hoặc getImageData() trên một canvas không bao giờ được thêm vào trang hiển thị. Công cụ dành cho nhà phát triển của trình duyệt và một số tiện ích mở rộng về quyền riêng tư có thể làm lộ những lệnh gọi này.
Một hook phát hiện tối giản
Bạn có thể tự chèn đoạn theo dõi vào canvas API để ghi lại các lần đọc đáng ngờ:
// Phát hiện các script đọc điểm ảnh canvas mà không hiển thị gì
(function watchCanvasReads() {
const origToDataURL = HTMLCanvasElement.prototype.toDataURL;
const origGetImageData = CanvasRenderingContext2D.prototype.getImageData;
HTMLCanvasElement.prototype.toDataURL = function (...args) {
if (!document.body.contains(this)) {
console.warn('[canvas-fp] toDataURL() on an off-screen canvas', this);
}
return origToDataURL.apply(this, args);
};
CanvasRenderingContext2D.prototype.getImageData = function (...args) {
if (!document.body.contains(this.canvas)) {
console.warn('[canvas-fp] getImageData() on an off-screen canvas', this.canvas);
}
return origGetImageData.apply(this, args);
};
})();
Hãy chạy nó trước các script của chính trang web (bằng userscript ở thời điểm document_start, hoặc dán vào console rồi tải lại trang), sau đó theo dõi các cảnh báo trên một trang không hề có nội dung đồ họa nào. Cảnh báo nhầm là điều khó tránh: các widget chỉnh sửa ảnh, thư viện biểu đồ và công cụ cắt ảnh vốn dĩ phải đọc lại điểm ảnh. Tín hiệu thực sự đáng ngờ là một lượt đọc ngược trên canvas chưa từng được gắn vào tài liệu, ở một trang không có bất kỳ tính năng đồ họa nào.
Nếu bạn muốn xem chính dấu vân tay của mình thay vì đọc code, cách đơn giản nhất là chạy công cụ phát hiện dấu vân tay của BrowserInsight. Nó tính giá trị băm canvas trực tiếp của bạn, hiển thị các tín hiệu WebGL và âm thanh bên cạnh, và ước tính dấu vân tay tổng thể của bạn độc nhất đến mức nào — đúng con đường đọc ngược mà một kẻ theo dõi sẽ dùng, nhưng chạy hoàn toàn trong trình duyệt của bạn và không gửi lên máy chủ.
Các biện pháp phòng vệ và sự đánh đổi của chúng
Không có biện pháp phòng vệ nào là hoàn hảo, và — điều quan trọng — một số lựa chọn phổ biến lại có thể khiến bạn dễ nhận diện hơn. Hơn nữa, không có hai nhân trình duyệt nào xử lý việc đọc ngược canvas giống nhau, và một tuyên bố chung chung kiểu "trình duyệt có thể thêm nhiễu" lại che lấp đúng những khác biệt quan trọng khi bạn phải chọn một biện pháp. Sau đây là những gì mỗi nhà cung cấp thực sự triển khai hiện nay.
Đồng nhất (resistFingerprinting của Firefox và Tor Browser)
Tùy chọn tích hợp sẵn privacy.resistFingerprinting của Firefox — cùng chế độ bảo vệ được Mozilla ghi lại trong tài liệu và được bật mặc định trong Tor Browser, vốn xây dựng trên nền Firefox — đi theo hướng tiếp cận đồng nhất: một lượt đọc ngược canvas (toDataURL() hoặc getImageData()) sẽ trả về một ảnh trắng trơn, trừ khi bạn tự tay chấp thuận hộp thoại xin quyền; còn các tín hiệu entropy cao khác — chuỗi vendor và renderer của WebGL, thông số màn hình, múi giờ — đều được báo về dưới dạng giá trị cố định, chung chung mà mọi người dùng được bảo vệ đều giống nhau. Nhờ vậy, thứ script nhận được hoặc là một kết quả vô dụng, hoặc là một giá trị y hệt nhau trên toàn bộ nhóm người dùng được bảo vệ. Hòa lẫn vào một đám đông lớn và đồng nhất là biện pháp phòng vệ vững chắc nhất — nhưng cái giá phải trả là một trải nghiệm duyệt web bị chuẩn hóa nặng nề, đôi khi hạn chế, và chính vì sự đánh đổi đó mà Mozilla triển khai nó như một tùy chọn tự bật thay vì mặc định trên Firefox.
Ngẫu nhiên hóa (farbling của Brave)
Brave đi theo một con đường khác gọi là farbling: theo tài liệu của Brave, nó thêm nhiễu nhỏ, xác định và theo từng phiên/từng eTLD+1 vào việc đọc ngược canvas — cùng một trang thấy một giá trị giả nhất quán trong một phiên, nhưng một giá trị khác ở phiên sau hoặc trên một trang khác, nên việc liên kết xuyên trang bị phá vỡ. Rủi ro tinh tế là bản thân việc bị ngẫu nhiên hóa lại có thể bị phát hiện — và ngẫu nhiên hóa triển khai ngây thơ có thể nghịch lý thay thêm vào entropy, vì "một trình duyệt có canvas nhiễu" tự nó là một đặc điểm phân biệt. Farbling được thiết kế tốt giữ cho nhiễu nhỏ, xác định và hợp lý để tránh cái bẫy này. Để tìm hiểu sâu hơn về cách thiết kế noise quyết định liệu ngẫu nhiên hóa có giúp ích hay phản tác dụng, xem Nhiễu Canvas so với hash thật: vì sao ngẫu nhiên hóa lại phản tác dụng.
Lập trường bảo vệ chống theo dõi của WebKit/Safari
Safari hoàn toàn không dựa vào nhiễu dành riêng cho canvas. Tài liệu Tracking Prevention của WebKit mô tả một chiến lược rộng hơn xây dựng trên Intelligent Tracking Prevention: phân vùng lưu trữ theo từng trang cấp cao nhất, giới hạn quyền truy cập của script vào dữ liệu xuyên trang, và coi việc nhận diện xuyên trang mang tính bền vững nói chung là một kiểu lạm dụng cần bị chặn, thay vì một thứ cần được che đậy theo từng API riêng lẻ. Việc đọc canvas vẫn hoạt động bình thường trên Safari, nhưng chính việc liên kết xuyên trang xung quanh nó — thứ khiến một dấu vân tay trở nên có giá trị với kẻ theo dõi — mới là điều ITP nhắm tới.
Chrome và Chromium nguyên bản (không có biện pháp nào)
Điều này đáng nói thẳng, vì nó đúng với phần lớn người đọc: Chrome không có biện pháp phòng vệ nào dành riêng cho canvas. toDataURL() và getImageData() trả về đúng những điểm ảnh mà GPU và bộ phông chữ của bạn đã kết xuất, ở cả cửa sổ thường lẫn cửa sổ ẩn danh; các trình duyệt nền Chromium không tự vá nhân cũng vậy — Brave ở trên là ngoại lệ đáng chú ý. Công việc về quyền riêng tư của Google ở mảng này nhắm vào phần đường ống xuyên trang (chính sách cookie bên thứ ba, các API Privacy Sandbox), chứ không nhằm làm cho canvas trở nên không đọc được. Nếu bạn dùng Chrome nguyên bản, hãy coi như giá trị băm canvas của mình đã lộ hoàn toàn.
Tiện ích chặn (CanvasBlocker)
Các tiện ích như CanvasBlocker có thể chặn việc đọc ngược, trả về một giá trị giả, hoặc ngẫu nhiên hóa theo từng tên miền. Chúng cho bạn quyền kiểm soát tinh tế, nhưng vẫn kèm theo lưu ý cũ: một giá trị giả mạo bất thường hoặc quá lộ liễu có thể trở nên nổi bật, và một bộ chặn cấu hình kém có thể là một tín hiệu mạnh hơn cả cái canvas mà nó che giấu.
Tắt JavaScript
Tắt JavaScript (qua NoScript hoặc tương tự) vô hiệu hoàn toàn canvas fingerprinting, vì API không thể chạy. Sự đánh đổi rất lớn — hầu hết website hiện đại sẽ hỏng nếu thiếu nó — nên cách này chỉ phù hợp với những quy trình nhạy cảm nhất về bảo mật.
| Biện pháp | Cách hoạt động | Đánh đổi chính |
|---|---|---|
| resistFingerprinting của Firefox / Tor Browser | Giá trị đồng nhất hoặc chặn đọc ngược | Trải nghiệm bị hạn chế, chuẩn hóa |
| Farbling của Brave | Nhiễu theo phiên, theo trang phá vỡ liên kết | Ngẫu nhiên hóa có thể bị phát hiện |
| Safari (WebKit ITP) | Chặn liên kết xuyên trang, không chặn bản thân API | Lượt đọc canvas vẫn thành công; phạm vi hẹp hơn |
| Chrome / Chromium nguyên bản | Không có biện pháp nào — trả về điểm ảnh thật | Không có gì để thiết lập |
| CanvasBlocker | Chặn/giả mạo/ngẫu nhiên hóa việc đọc ngược | Cấu hình sai có thể phản tác dụng |
| Tắt JavaScript | API không bao giờ chạy | Làm hỏng hầu hết website |
Câu hỏi thường gặp
Xóa cookie có loại bỏ dấu vân tay canvas của tôi không?
Không. Canvas fingerprinting không lưu gì trên thiết bị của bạn — nó suy ra mã định danh từ cách phần cứng và phần mềm của bạn kết xuất đồ họa. Xóa cookie, cache hay dữ liệu trang không có tác dụng gì với nó.
Chế độ riêng tư hay ẩn danh có chặn được canvas fingerprinting không?
Thường là không. Cửa sổ riêng tư cô lập cookie và lịch sử, nhưng GPU, driver và phông chữ của bạn không đổi, nên giá trị băm canvas thường giống như ở cửa sổ bình thường. Chế độ riêng tư giúp ích cho việc theo dõi dựa trên lưu trữ, chứ không phải fingerprinting.
Một website có thể thấy tôi đang dùng bộ chặn canvas không?
Đôi khi có. Nếu canvas của bạn trả về một giá trị giả mạo, rỗng hoặc nhiễu một cách rõ ràng, một script tinh vi có thể suy ra rằng một biện pháp bảo vệ đang hoạt động. Đó là lý do tại sao tính đồng nhất (trông giống mọi người) thường vững chắc hơn ngẫu nhiên hóa (trông khác biệt một cách cố ý).
Canvas fingerprinting có giống với WebGL fingerprinting không?
Chúng có liên quan nhưng khác biệt. Canvas đọc việc kết xuất 2D của chữ và hình khối; WebGL dò GPU của bạn qua kết xuất 3D và lộ trực tiếp các chuỗi vendor và renderer. Chúng bổ sung cho nhau trong một dấu vân tay kết hợp — bài phân tích sâu về WebGL fingerprinting của chúng tôi trình bày chi tiết về phía 3D.


