1 điểm bởi GN⁺ 14 ngày trước | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • 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 150ESR 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 150ESR 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
  • 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 trong OpenDatabaseOp::DoDatabaseWork()
  • Khi aIsPrivate là 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 trong StorageDatabaseNameHashtable toà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 qua QuotaClient::GetDatabaseFilenames(...) trong GetDatabasesOp::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
  • 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
  • Đ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 N tên cơ sở dữ liệu, số hoán vị có thể quan sát là N!
    • Entropy lý thuyết là log2(N!)
  • 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ư

Chưa có bình luận nào.

Chưa có bình luận nào.