Chúng tôi đã phát hiện một mã định danh Firefox ổn định có thể liên kết mọi danh tính Tor riêng tư của người dùng
(fingerprint.com)- Chỉ riêng thứ tự trả về của
indexedDB.databases()cũng có thể tạo ra một mã định danh ổn định được duy trì trong suốt vòng đời tiến trình trên các trình duyệt dựa trên Firefox - Mã định danh này được chia sẻ vượt ra ngoài phạm vi origin, nên cả các trang không liên quan cũng có thể quan sát cùng một giá trị trong cùng một runtime trình duyệt và dùng nó cho theo dõi cross-origin
- Trong Private Browsing của Firefox, nếu tiến trình vẫn còn sống thì mã định danh vẫn được giữ lại ngay cả sau khi đóng mọi cửa sổ riêng tư; trong Tor Browser, nó vẫn tồn tại cả sau New Identity
- Nguyên nhân nằm ở cách triển khai IndexedDB của Gecko ánh xạ tên cơ sở dữ liệu riêng tư sang tên tệp dựa trên UUID và để lộ kết quả đó mà không sắp xếp
- Mozilla đã phát hành bản sửa trong Firefox 150 và ESR 140.10.0; thiết kế không để lộ thứ tự lưu trữ nội bộ ra bên ngoài là rất quan trọng để bảo vệ quyền riêng tư
Tổng quan lỗ hổng
- Trên mọi trình duyệt dựa trên Firefox, có thể trích xuất một mã định danh tồn tại trong suốt vòng đời tiến trình thông qua thứ tự các mục mà
indexedDB.databases()trả về- Nếu một website tạo nhiều cơ sở dữ liệu IndexedDB rồi kiểm tra thứ tự trả về, nó có thể tạo ra một mã định danh duy nhất và có tính xác định cho tiến trình trình duyệt đang chạy
- Hành vi này không xuất hiện ở phạm vi origin mà ở phạm vi tiến trình, nên cả các trang không liên quan cũng có thể quan sát cùng một mã định danh trong cùng một runtime trình duyệt
- Trong Private Browsing của Firefox, nếu tiến trình Firefox vẫn tiếp tục chạy thì mã định danh vẫn được giữ lại ngay cả sau khi đóng mọi cửa sổ riêng tư
- Trong Tor Browser, mã định danh ổn định này vẫn tồn tại sau New Identity, thao tác xóa cookie, lịch sử duyệt web và sử dụng một mạch Tor mới
- Điều này mâu thuẫn với kỳ vọng rằng hoạt động duyệt web về sau không nên bị liên kết với hoạt động trước đó, làm suy yếu bảo đảm không thể liên kết mà người dùng đang dựa vào
- Đã thực hiện công bố có trách nhiệm với Mozilla và Tor Project
- Mozilla đã phát hành bản sửa trong Firefox 150 và ESR 140.10.0
- Bản vá đang được theo dõi trong Mozilla Bug 2024220, và nguyên nhân nằm trong cách triển khai IndexedDB của Gecko, nên cũng liên quan tới Tor Browser và các trình duyệt khác dựa trên Firefox
- Nguyên lý sửa lỗi khá đơn giản
- Trình duyệt không được để lộ thứ tự lưu trữ nội bộ ở phạm vi tiến trình ra bên ngoài
- Nếu chuẩn hóa hoặc sắp xếp kết quả trước khi trả về thì có thể loại bỏ entropy và chặn việc lạm dụng làm mã định danh ổn định
Vì sao điều này quan trọng
- Chế độ duyệt web riêng tư và các trình duyệt chú trọng quyền riêng tư đều nhằm khiến việc nhận diện người dùng giữa các ngữ cảnh khác nhau trở nên khó khăn hơn
- Kỳ vọng phổ biến 1: nếu không có cơ chế danh tính rõ ràng hay lưu trữ dùng chung, các trang không liên quan sẽ không thể biết liệu chúng có đang tương tác với cùng một phiên bản trình duyệt hay không
- Kỳ vọng phổ biến 2: khi một phiên riêng tư kết thúc, thông tin gắn với phiên đó cũng phải biến mất
- Hành vi lần này phá vỡ cả hai kỳ vọng
- Các trang có thể suy ra mã định danh chỉ từ hành vi lưu trữ nội bộ của trình duyệt, ngay cả khi không có cookie, localStorage hay kênh cross-site tường minh
- Có thể lấy được tín hiệu nhận diện dung lượng cao từ thứ tự tên cơ sở dữ liệu mà API trả về
- Có bài học dành cho nhà phát triển
- Lỗ hổng quyền riêng tư không chỉ phát sinh từ việc truy cập trực tiếp vào dữ liệu nhận dạng
- Chúng cũng có thể gây rò rỉ quyền riêng tư khi các chi tiết triển khai nội bộ bị để lộ một cách có tính xác định
- Điểm mấu chốt từ góc nhìn bảo mật và sản phẩm
- Một API nhìn qua có vẻ vô hại cũng có thể trở thành vector theo dõi cross-site nếu nó làm rò rỉ trạng thái ở cấp tiến trình ổn định
IndexedDB và indexedDB.databases()
- IndexedDB là API trình duyệt để lưu trữ dữ liệu có cấu trúc ở phía client
- Ứng dụng web dùng nó cho hỗ trợ ngoại tuyến, bộ nhớ đệm, trạng thái phiên và các mục đích lưu trữ cục bộ khác
- Mỗi origin có thể tạo một hay nhiều cơ sở dữ liệu có tên, đồng thời lưu object store và dữ liệu dung lượng lớn
indexedDB.databases()trả về metadata của các cơ sở dữ liệu mà origin hiện tại có thể nhìn thấy- Nhà phát triển có thể dùng nó để kiểm tra cơ sở dữ liệu hiện có, debug mức sử dụng lưu trữ, hoặc quản lý trạng thái ứng dụng
- Theo kỳ vọng bình thường về quyền riêng tư, bản thân thứ tự trả về của API này không được chứa thông tin nhận dạng
- Cần có cách biểu diễn metadata cơ sở dữ liệu trung lập hoặc đã được chuẩn hóa
- Vấn đề thực tế là trên các trình duyệt dựa trên Firefox, thứ tự trả về hoàn toàn không hề trung lập
Cách indexedDB.databases() trở thành mã định danh ổn định
- Trong Private Browsing của Firefox,
indexedDB.databases()không trả về metadata theo thứ tự tạo cơ sở dữ liệu mà theo thứ tự bắt nguồn từ cấu trúc lưu trữ nội bộ- Vị trí triển khai liên quan là
dom/indexedDB/ActorsParent.cpp
- Vị trí triển khai liên quan là
- Trong Private Browsing, tên cơ sở dữ liệu không được dùng trực tiếp làm mã định danh trên đĩa
- Thay vào đó, nó được ánh xạ sang phần gốc tên tệp dựa trên UUID thông qua bảng băm toàn cục
StorageDatabaseNameHashtable = nsTHashMap<nsString, nsString> - Ánh xạ này được thực hiện trong
GetDatabaseFilenameBase()bên trongOpenDatabaseOp::DoDatabaseWork()
- Thay vào đó, nó được ánh xạ sang phần gốc tên tệp dựa trên UUID thông qua bảng băm toàn cục
- Khi
aIsPrivatelà true, tên cơ sở dữ liệu do site cung cấp sẽ được thay thế bằng UUID được tạo ra và lưu trongStorageDatabaseNameHashtabletoàn cục- Khóa chỉ dùng chính chuỗi tên cơ sở dữ liệu
- Tồn tại trong suốt vòng đời của IndexedDB QuotaClient
- Được chia sẻ giữa mọi origin
- Chỉ được đặt lại khi khởi động lại hoàn toàn Firefox
- Về sau, khi gọi
indexedDB.databases(), Firefox thu thập tên tệp cơ sở dữ liệu thông quaQuotaClient::GetDatabaseFilenames(...)trongGetDatabasesOp::DoDatabaseWork()- Tên gốc của cơ sở dữ liệu được chèn vào
nsTHashSet - Không thực hiện bất kỳ thao tác sắp xếp nào trước khi lặp
- Tên gốc của cơ sở dữ liệu được chèn vào
- Thứ tự kết quả cuối cùng được quyết định bởi cách duyệt layout bucket nội bộ của hash set
- Vì ánh xạ UUID được giữ ổn định trong suốt vòng đời tiến trình Firefox, nên thứ tự trả về cũng được giữ như một hàm xác định của giá trị UUID được tạo, hành vi của hàm băm, dung lượng bảng băm và lịch sử chèn
- Thứ tự này được giữ xuyên suốt các tab và cửa sổ riêng tư, và chỉ được đặt lại khi khởi động lại hoàn toàn Firefox
- Cả ánh xạ UUID lẫn việc duyệt hash set đều không ở phạm vi origin mà ở phạm vi tiến trình
Cách tái hiện
- Chỉ với một PoC đơn giản cũng có thể chứng minh hành vi này
- Hai origin khác nhau cùng host một script giống nhau
- Mỗi script tạo các cơ sở dữ liệu với một tập tên cố định, gọi
indexedDB.databases(), trích xuất thứ tự trả về rồi in ra
- Trên các bản Firefox Private Browsing và Tor Browser bị ảnh hưởng, hai origin sẽ quan sát cùng một hoán vị trong suốt vòng đời của cùng tiến trình trình duyệt
- Khi khởi động lại trình duyệt, hoán vị sẽ thay đổi
- Có đưa ra ví dụ đầu ra mang tính khái niệm
- Thứ tự tạo:
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p - Thứ tự trả về:
g,c,p,a,l,f,n,d,j,b,o,h,e,m,i,k
- Thứ tự tạo:
- Điểm cốt lõi không nằm ở chính thứ tự cụ thể đó
- Nó khác với thứ tự tạo ban đầu
- Cùng một thứ tự xuất hiện ở các origin không liên quan
- Nó vẫn được giữ qua các lần tải lại, cửa sổ riêng tư mới và cả sau khi đóng mọi cửa sổ riêng tư
- Chỉ khi khởi động lại toàn bộ trình duyệt mới sinh ra thứ tự mới
- Có thể trực tiếp xác nhận những đặc tính không mong muốn này từ góc nhìn quyền riêng tư
Tác động đến quyền riêng tư
- Lỗ hổng này cho phép cả theo dõi cross-origin lẫn same-origin trong cùng một runtime trình duyệt
-
Tác động cross-origin
- Các website không liên quan có thể độc lập suy ra cùng một mã định danh để kết luận rằng chúng đang tương tác với cùng một tiến trình Firefox hoặc Tor Browser đang chạy
- Có thể liên kết hoạt động giữa các domain ngay cả khi không có cookie hay cơ chế lưu trữ dùng chung khác
-
Tác động same-origin
- Trong Firefox Private Browsing, nếu tiến trình Firefox vẫn đang chạy thì mã định danh vẫn được giữ lại cả sau khi đóng mọi cửa sổ riêng tư
- Một site có thể nhận ra lại những lần truy cập sau đó dù bề ngoài có vẻ như là một phiên riêng tư mới
- Trong Tor Browser, mã định danh ổn định này trên thực tế làm vô hiệu hóa cơ chế cô lập của New Identity trong tiến trình trình duyệt đang chạy
- Nó cho phép liên kết giữa các phiên vốn phải được tách biệt hoàn toàn
-
Vì sao đặc biệt nghiêm trọng trong Tor Browser
- Tor Browser được thiết kế để giảm khả năng liên kết cross-site và tối thiểu hóa nhận dạng ở cấp phiên bản trình duyệt
- Một mã định danh ổn định tồn tại trong suốt vòng đời tiến trình đi ngược trực diện với mục tiêu thiết kế này
- Dù nó chỉ tồn tại cho đến khi khởi động lại toàn bộ tiến trình, như vậy vẫn đủ để làm suy yếu tính không thể liên kết trong quá trình sử dụng thực tế
Entropy và dung lượng fingerprinting
- Tín hiệu này không chỉ ổn định mà còn có dung lượng cao
- Nếu một site kiểm soát
Ntên cơ sở dữ liệu, số hoán vị có thể quan sát làN! - Entropy lý thuyết là
log2(N!)
- Nếu một site kiểm soát
- Với 16 tên có thể kiểm soát, không gian lý thuyết vào khoảng 44 bit
- Mức này đủ để phân biệt các phiên bản trình duyệt đồng thời trong môi trường thực tế
- Số hoán vị thực tế có thể đạt được có thể thấp hơn đôi chút do hành vi của bảng băm nội bộ
- Tuy vậy, điểm cốt lõi về mặt bảo mật không thay đổi
- Thứ tự bị lộ vẫn cung cấp đủ entropy để hoạt động như một mã định danh mạnh
Cách sửa
- Cách sửa đúng là chấm dứt việc để lộ entropy bắt nguồn từ layout lưu trữ nội bộ
- Biện pháp giảm thiểu gọn gàng nhất là trả kết quả theo một thứ tự chuẩn như sắp xếp từ điển
- Cách này vẫn giữ được tính hữu ích của API cho nhà phát triển đồng thời loại bỏ tín hiệu fingerprinting
- Việc ngẫu nhiên hóa đầu ra ở mỗi lần gọi cũng có thể che giấu thứ tự ổn định
- Tuy nhiên, sắp xếp đơn giản hơn, dễ dự đoán hơn và là lựa chọn dễ hiểu hơn với nhà phát triển
- Các điều kiện của một bản sửa lý tưởng từ góc độ kỹ thuật bảo mật
- Độ phức tạp khái niệm thấp
- Rủi ro tương thích tối thiểu
- Loại bỏ trực tiếp rò rỉ quyền riêng tư
Công bố có trách nhiệm
- Đã thực hiện công bố có trách nhiệm với Mozilla và Tor Project
- Mozilla đã phát hành bản sửa trong Firefox 150 và ESR 140.10.0
- Bản vá đang được theo dõi trong Mozilla Bug 2024220
- Nguồn gốc của hành vi này nằm trong cách triển khai IndexedDB của Gecko
- Các trình duyệt hậu duệ khác dựa trên Gecko, bao gồm cả Tor Browser, cũng nằm trong vùng ảnh hưởng nếu không có biện pháp giảm thiểu riêng
Thiết kế lấy quyền riêng tư làm trung tâm
- Ngay cả những chi tiết triển khai nhỏ cũng có thể dẫn tới vấn đề quyền riêng tư đáng kể
- Các website không liên quan có thể liên kết hoạt động vượt qua origin trong cùng một runtime trình duyệt
- Mã định danh tồn tại lâu hơn kỳ vọng của người dùng, làm suy yếu ranh giới của phiên riêng tư
- Điểm tích cực là cách sửa vừa đơn giản vừa hiệu quả
- Chuẩn hóa đầu ra trước khi trả về có thể loại bỏ nguồn entropy này
- Có thể khôi phục lại các ranh giới quyền riêng tư như mong đợi
- Đây là kiểu lỗ hổng dễ bị bỏ sót nhưng tác động lớn, và rất đáng được chú ý trong quá trình xây dựng các tính năng nhạy cảm với quyền riêng tư
1 bình luận
Ý kiến trên Hacker News
Tôi cảm thấy nghiên cứu này thực sự ấn tượng và bài viết cũng được viết rất hay
Tôi cứ tưởng cuối bài sẽ có quảng cáo sản phẩm, nhưng lại không có nên càng thấy bất ngờ
Tuy vậy, nếu sản phẩm của công ty này có làm fingerprinting thì tôi vẫn thắc mắc vì sao họ lại báo lỗ hổng này cho Mozilla
Dù có thể là không đạo đức, nhưng nếu muốn tạo khác biệt với đối thủ thì xét về kinh doanh chẳng phải giữ kín sẽ có lợi hơn sao
Tôi hiếm khi thấy các tác nhân đe dọa tự đốt zero-day của mình bằng cách công bố có trách nhiệm
Như bài viết nói, mã định danh này có thể tồn tại chừng nào tiến trình Firefox còn sống, nên với Tor Browser thì nhất định phải tắt hẳn sau khi kết thúc phiên
Cũng quan trọng là không trộn nhiều mục đích sử dụng khác nhau trong cùng một phiên
Link OP đưa bị timeout trong môi trường Tor của tôi, nhưng bản Wayback thì mở bình thường
Ngoài ra tôi cũng tò mò không biết có nhà nghiên cứu học thuật nào làm về chủ đề này không
Tôi biết các tổ chức như EFF có hoạt động trong lĩnh vực này, nhưng tôi đang tìm nhiều hơn về phía giáo sư đại học hoặc các viện nghiên cứu thuần túy như MSR, PARC hơn là các nhà hoạt động NGO
Với một người rất quan tâm đến quyền riêng tư như tôi, dù có thể tăng cường bảo mật khá nhiều bằng bộ ba cá nhân holy trinity là noscript, ublock origin và firefox containers, thì tính ẩn danh vẫn cứ như tuột qua kẽ tay vì fingerprinting
Nếu mở rộng fingerprinting đến cả stylometry thì lại càng đúng hơn
Ví dụ, tìm các hội nghị như PETS sẽ hữu ích
Bản thân tôi thấy khó hiểu ở chỗ website có thể truy cập kiểu thông tin này mà không hề hỏi hay thông báo cho người dùng
Tôi thắc mắc vì sao trình duyệt không được thiết kế giống điện thoại, tức là phải xin cấp quyền khi máy chủ hay ứng dụng muốn truy cập các thông tin như thế
User agent cho biết phiên bản trình duyệt thì cũng khá hợp lý, còn việc hỏi hệ thống có những font nào cũng khó mà loại bỏ hoàn toàn nếu vẫn muốn hỗ trợ hiển thị phông chữ
Múi giờ, ngôn ngữ, bố cục bàn phím, kích thước màn hình và kích thước cửa sổ cũng đều cần cho hoạt động web bình thường
Việc biết trình phát video hay âm thanh hỗ trợ định dạng nào để gửi đúng media cũng là điều hiển nhiên
Chỉ cần JavaScript đọc được thời gian thì việc so với thời gian phía máy chủ để suy ra độ lệch đồng hồ hệ thống cũng là chuyện dễ
Cứ cộng dồn từng thứ như vậy, gần như mọi trình duyệt cuối cùng đều bị nhận diện thành duy nhất
Hơn nữa công ty đó cũng tài trợ một phần đáng kể cho đối thủ lớn nhất của mình
Vì vậy tôi không thấy thực tế này có gì đáng ngạc nhiên
Ứng dụng có thể truy cập mã định danh và đặc tính thiết bị nhiều hơn rất nhiều
Ngay cả trên những hệ thống được bảo vệ tương đối tốt và không có Google Play services thì tôi nghĩ vẫn vậy
Ngược lại, phía Apple lại đáng tiếc ở chỗ gần như không có kiểm soát chi tiết
Vì trình duyệt giờ đã có độ phức tạp ngang ngửa OS, nên bất kỳ phần nào của hệ thống cũng có thể vô tình bị lộ ra và bị lạm dụng
Cụm từ process-scoped trong bài khiến tôi hơi bối rối
Tôi nhớ là vào năm 2021 Mozilla đã công bố tính năng one-process-per-site thử nghiệm cho Firefox và giải thích rằng họ đang tạo ranh giới ở mức tiến trình hệ điều hành giữa mọi website trên Firefox desktop
Bài liên quan là Introducing Site Isolation in Firefox
Nên tôi thắc mắc không biết tính năng này vẫn chưa được triển khai hoàn toàn, hay là đã triển khai rồi nhưng IndexedDB lại nằm ngoài lớp cô lập đó
Nếu vậy thì đây là một giải thích khá thú vị
Theo mô tả này thì có vẻ chỉ cần khởi động lại trình duyệt là nó không còn được giữ lại nữa, vậy nếu thế thì với kẻ tấn công tính hữu dụng chẳng phải giảm đi khá nhiều sao
Trong Firefox Private Browsing, ngay cả khi đóng toàn bộ cửa sổ riêng tư thì nếu tiến trình Firefox vẫn còn sống, mã định danh vẫn có thể được giữ nguyên
Còn với Tor Browser, tôi hiểu là ngay cả khi dùng New Identity — vốn được thiết kế như một lần reset hoàn toàn bằng cách xóa cookie, lịch sử truy cập và dùng mạch Tor mới — thì mã định danh ổn định này vẫn tồn tại
Đầu tiên website fingerprint trình duyệt và lưu ID cùng fingerprint vào cookie
Ở phiên sau, nó fingerprint lại rồi so với cookie; nếu giá trị thay đổi thì nó gửi cả fingerprint cũ lẫn fingerprint mới lên máy chủ để nối chúng lại với nhau
Cơ quan nhà nước có thể đã biết hoặc theo dõi được nhiều node, và khi đối chiếu chéo nhiều loại metadata thì có thể nhận diện con người khá chính xác
Cũng không nhất thiết lúc nào cũng phải chính xác 100%, chỉ cần thu thập được nhiều thông tin gián tiếp ngoài chính mục tiêu, như thông tin khu vực xung quanh hay từ bên kia bức tường, là cũng đủ
Tôi cảm nhận đây là một kiểu nhận diện bằng thông tin proxy
Thành thật mà nói, phần lớn Web Standards có vẻ được dùng cho fingerprinting nhiều hơn là cho chức năng thực tế
IndexedDB dường như cũng chỉ có số ít website dùng thật sự để lưu trữ, tôi không rõ ai là người thực sự cần nó đến vậy
Vì thế tôi cho rằng chính hướng tiếp tục mở rộng chuẩn web đã là sai lầm
Trình duyệt nên chỉ cung cấp các API tối thiểu để tương tác với thiết bị, còn những thứ như IndexedDB có thể được triển khai bằng thư viện WebAssembly sao cho không làm rò rỉ dữ liệu có giá trị
Ví dụ, nếu canvas chỉ cho truy cập bộ đệm hình ảnh mà không có các routine vẽ gọi thư viện theo từng nền tảng, thì giá trị fingerprinting của nó có lẽ đã giảm đi rất nhiều
Những trường hợp tôi từng thấy cho đến nay gồm những nơi như gmail dùng nó để cache hình ảnh tồn tại lâu, hoặc dùng như một cách khác để giữ trạng thái đăng nhập thay vì cookie
Tôi hơi rối ở chỗ này
Nếu UUID của IndexedDB được chia sẻ giữa mọi origin, thì chẳng phải có thể nhận diện trình duyệt dựa vào chính nội dung cơ sở dữ liệu thay vì thứ tự hay sao
Một trang nào đó tạo các cơ sở dữ liệu
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,prồi truy vấn thứ tự, và theo ánh xạ tên-UUID toàn cục nó có thể nhận được kết quả kiểu nhưg,c,p,a,l,f,n,d,j,b,o,h,e,m,i,kLỗ hổng cốt lõi là chừng nào tiến trình Firefox còn sống, thì bất kỳ website nào tạo cùng một tập tên cơ sở dữ liệu cũng sẽ nhìn thấy chính xác cùng một thứ tự, bất kể nội dung bên trong là gì
Vì vậy đây trở thành một mã định danh ổn định, entropy cao theo thời gian, tức một fingerprint
Nó được chia sẻ vượt qua origin, và ngay cả sau khi xóa dữ liệu trang, chỉ cần tạo lại với cùng tên là có thể lấy lại fingerprint thông qua thứ tự đó
Nếu không thì IndexedDB đã trở thành một evercookie quá dễ rồi
Tôi hiểu là mỗi origin chỉ được lộ ra tập con các cơ sở dữ liệu gắn với origin đó
Tôi từng thắc mắc không biết Tor Browser bây giờ vẫn cho phép JavaScript theo mặc định hay không
Theo cách tôi hiểu thì nếu chặn JavaScript chạy, có lẽ cũng sẽ không bị ảnh hưởng bởi lỗ hổng này
Không có nhiều người dùng tắt JS, nên bạn lập tức rơi vào một nhóm nhỏ hơn rất nhiều và trong nhóm đó lại càng dễ trở nên duy nhất
Dĩ nhiên không có JS thì số lựa chọn để thu thập chi tiết sẽ ít hơn, nhưng bù lại chỉ với ít thông tin hơn cũng dễ phân biệt hơn
Hơn nữa, Tor Browser kỳ lạ ở chỗ hoàn toàn không spoof
navigator.platform, nên dù User-Agent giả làm Windows thì website vẫn nhìn ra bạn đang dùng Linux