Chrome đang thử API vẽ HTML thật vào canvas. Bài viết phân tích đề xuất loại gì khỏi điểm ảnh và vẫn để lại gì cho script đọc được.
Chrome đang thử nghiệm một API cho phép <canvas> vẽ HTML thật, có định dạng, thay vì chỉ vẽ đường, hình chữ nhật và chuỗi văn bản. Điều này đặt ra câu hỏi quyền riêng tư ngay lập tức: điểm ảnh của canvas có thể đọc ngược lại, và đọc điểm ảnh canvas chính là nền tảng của canvas fingerprinting. Nếu canvas giờ có thể chứa một trang đã render, script có thể đọc ra được gì? Các tác giả đề xuất trả lời bằng một danh sách cụ thể những thứ tuyệt đối không được vẽ. Bài viết này đi qua danh sách đó và ý nghĩa của nó. Đây là một thử nghiệm, không phải tính năng đã phát hành.
Điểm chính
- HTML-in-Canvas là đề xuất trong origin trial của Chrome, không phải chuẩn web đã phát hành. Theo bài đăng của chính Chrome, đợt thử nghiệm kéo dài đến Chrome 160 và tên phương thức đã đổi (ví dụ ở Chrome 155).
- Quy tắc riêng tư cốt lõi là "read-back-allowed rendering": vẽ một phần tử không được tiết lộ thông tin nhạy cảm mà mã của trang vốn không thể quan sát.
- Tài liệu giải thích loại khỏi kết quả vẽ: nội dung cross-origin, màu và giao diện hệ thống, dấu kiểm tra chính tả, trạng thái liên kết đã truy cập, autofill đang chờ và khử răng cưa văn bản subpixel.
- Tài liệu cố ý giữ lại những gì nó coi là vốn đã phát hiện được, như hình thức thanh cuộn và điều khiển biểu mẫu, tần suất nhấp nháy con trỏ và
forced-colors. - Đây không phải kỹ thuật fingerprinting đang tồn tại, mà là một thiết kế cố gắng không tạo ra kỹ thuật mới.
API này làm gì
Hiện nay canvas chỉ vẽ các hình nguyên thủy. Bạn có thể vẽ chuỗi bằng fillText(), nhưng không thể đưa cho nó một <div> có bố cục, xuống dòng và điều khiển biểu mẫu. Đề xuất HTML-in-Canvas, phát triển trong kho WICG, bổ sung khả năng chụp một phần tử và vẽ vào canvas 2D, WebGL hoặc WebGPU; với 2D, phương thức là drawElementImage(). Bài của Chrome về thay đổi origin trial nêu rằng đợt thử kéo dài đến Chrome 160 và một số phương thức, thuộc tính đã đổi tên ở Chrome 155, nên mọi đoạn mã bạn thấy chỉ là tạm thời. Tính năng cũng có mục trên Chrome Platform Status.
Động lực chủ yếu là sáng tạo và thực dụng: hiệu ứng trên HTML thật, văn bản trong cảnh 3D, nội dung có thể truy cập bên trong canvas. Quyền riêng tư là ràng buộc của thiết kế, không phải mục tiêu.
Vì sao canvas là bề mặt nhạy cảm
Canvas không chỉ là đầu ra. Script có thể gọi toDataURL() hoặc getImageData() để lấy lại từng điểm ảnh dưới dạng dữ liệu. Đó chính là cách canvas fingerprinting hoạt động: vẽ một cảnh cố định, đọc lại, băm. Mã băm khác nhau vì GPU, driver, bộ raster hoá font và hệ điều hành khác nhau. Xem thêm bức tranh rộng hơn trong hướng dẫn fingerprinting trình duyệt.
Giờ hãy hình dung một canvas có thể chứa trang đã render. Trình duyệt vẽ những thứ mà script của trang không thấy trực tiếp: liên kết đã truy cập hay chưa, màu giao diện hệ điều hành, bộ kiểm tra chính tả có gạch chân từ nào không. Nếu chúng rò vào điểm ảnh đã vẽ, script có thể đọc ngược ra, và một lệnh vẽ trông vô hại sẽ thành cửa sổ nhìn vào trạng thái riêng tư.
Quy tắc "read-back-allowed"
Tài liệu giải thích xử lý vấn đề bằng một nguyên tắc, gọi là read-back-allowed rendering. Theo lời của nó, việc vẽ phần tử và sự kiện paint liên quan "không được tiết lộ thông tin nhạy cảm về bảo mật hay quyền riêng tư mà mã tác giả vốn không quan sát được". Vì WebGL và WebGPU luôn đọc lại được điểm ảnh, cách an toàn là ngay từ đầu không đưa thông tin nhạy cảm vào kết quả vẽ. Văn bản mô tả đây là ngăn rò rỉ qua đọc điểm ảnh, tấn công thời gian và sự kiện invalidation. Nó không nhắc đến "fingerprinting" theo tên; đây là quy tắc bảo mật và riêng tư, còn cách đọc theo hướng fingerprinting bên dưới là của chúng tôi.
Những gì bị loại khỏi điểm ảnh
Tài liệu liệt kê những thứ phải loại khỏi kết quả vẽ:
- Dữ liệu cross-origin trong nội dung nhúng như iframe và ảnh, tham chiếu URL như
background-image, canvas bị "nhiễm" dữ liệu cross-origin và tham chiếu SVG. iframe cùng origin vẫn được vẽ; nội dung cross-origin bên trong thì không. - Màu, giao diện hoặc tuỳ chọn hệ thống.
- Dấu kiểm tra chính tả và ngữ pháp.
- Thông tin liên kết đã truy cập.
- Autofill biểu mẫu đang chờ mà JavaScript vốn không thấy.
- Khử răng cưa văn bản subpixel.
- Phụ đề và điều khiển video.
- Cửa sổ IME và định dạng văn bản đặc trưng của IME.
Phần lớn là những ứng viên rò rỉ hiển nhiên (liên kết đã truy cập và autofill là mục tiêu kinh điển của dò lịch sử). Với fingerprinting, mục thú vị nhất là khử răng cưa subpixel. Cách nền tảng làm mịn cạnh chữ phụ thuộc hệ điều hành, màn hình và cài đặt, và đó là một lý do cùng đoạn chữ trông hơi khác nhau trên các máy. fillText() thông thường trên canvas đã để lộ khá nhiều hành vi render này, vốn là nguyên liệu cốt lõi của fingerprinting font và render văn bản. Loại nó khỏi đường đi mới nghĩa là API mới không thêm cách đọc độ phân giải cao hơn.
Sự đối chiếu này quan trọng: đề xuất không sửa canvas fingerprinting hiện có; nó chỉ từ chối làm bề mặt rộng thêm.
Những gì cố ý giữ lại
Tài liệu cũng liệt kê những thông tin nó không coi là nhạy cảm trong bối cảnh này:
- văn bản find-in-page và dấu text-fragment;
- hình thức thanh cuộn và phần tử biểu mẫu, mà nó cho biết đã phát hiện được trong Blink và WebKit qua
foreignObject; - tần suất nhấp nháy con trỏ;
forced-colors, mà nó lưu ý JavaScript đã lấy được qua media query và màu hệ thống.
Lập luận nhất quán: nếu mã trang vốn đã quan sát được một giá trị thì vẽ nó ra không thêm thông tin mới. Quy tắc này hợp lý, nhưng cũng lộ ra giới hạn. Các tín hiệu như forced-colors vốn nằm trong những gì fingerprinting qua CSS media query thu thập, nên bên theo dõi vẫn lấy được dù thế nào. Đề xuất không tuyên bố giảm chúng.
Các đường đi qua GPU
Vấn đề đọc ngược cũng tồn tại ở phía GPU, và tài liệu nói rõ WebGL và WebGPU luôn đọc lại được điểm ảnh. Vì vậy các quy tắc loại trừ cũng áp dụng cho biến thể vẽ ảnh chụp phần tử vào các ngữ cảnh đó: hiện là texElementSubImage2D() cho WebGL và drawElementImageToTexture() cho WebGPU, cả hai tên đều đổi ở Chrome 155. Về những gì các ngữ cảnh này vốn đã tiết lộ, xem phân tích sâu WebGL fingerprinting và WebGPU fingerprinting.
Giới hạn cần nói thẳng
- Đây là đề xuất và thử nghiệm. Đợt thử của Chrome có thể thay đổi hoặc kết thúc, và rà soát riêng tư có thể sửa danh sách loại trừ.
- Chúng tôi không tìm thấy cam kết của các engine khác trên các trang được trích dẫn, nên không khẳng định gì về lập trường của Firefox hay Safari.
- Quy tắc trong tài liệu thiết kế chỉ tốt bằng bản triển khai. Các trường hợp biên (thời gian, invalidation, loại phần tử lạ) chính là nơi những quy tắc kiểu này hay rò, và đó là lý do tài liệu nêu đích danh tấn công thời gian.
- Không điều gì ở đây thay đổi những gì canvas fingerprinting làm được hôm nay.
Điều này có nghĩa gì với bạn
Với người truy cập: hiện chưa có gì thay đổi. Origin trial chỉ chạy trên các trang đã đăng ký tham gia và chỉ trong các phiên bản Chrome nằm trong thời hạn thử nghiệm; bạn không tự bật được. Nếu muốn giảm canvas fingerprinting dù sao đi nữa, hãy đọc vì sao nhiễu và ngẫu nhiên hoá canvas có thể phản tác dụng, và ưu tiên sự đồng nhất hơn ngẫu nhiên.
Với lập trình viên: nếu thử API, hãy coi tên là tạm thời và đừng trông chờ bắt được trạng thái nhạy cảm trong canvas — đó là chủ ý của thiết kế.
Kiểm tra mã băm canvas của bạn
Kiểm tra fingerprint của BrowserInsight tính mã băm canvas bằng API canvas 2D tiêu chuẩn, không dùng HTML-in-Canvas. Đây là cách tốt để thấy một script đọc canvas thông thường đã lấy được gì từ trình duyệt của bạn hôm nay.


