0

Tại sao tài khoản thứ hai lại bị xác minh: OAuth, state/PKCE và những gì nền tảng thực sự nhìn thấy

Khi phát triển một công cụ quản lý mạng xã hội theo mô hình Hootsuite, một trong những vấn đề kỹ thuật khó chịu nhất xuất hiện ngay ở bước đầu tiên: người dùng uỷ quyền tài khoản thứ nhất thành công, nhưng đến tài khoản thứ hai trên cùng một trình duyệt, nền tảng lập tức yêu cầu xác minh bổ sung: SMS, email, thậm chí tạm khoá. Phản xạ kỹ thuật thông thường là kiểm tra lại state và PKCE trong luồng OAuth. Nhưng hai cơ chế này không hề được thiết kế để giải quyết vấn đề đang xảy ra. Bài viết này phân tích vì sao, và từ đó rút ra nguyên tắc thiết kế cho một kiến trúc quản lý đa tài khoản tuân thủ ranh giới nền tảng.

OAuth bảo vệ điều gì, và không bảo vệ điều gì

state và PKCE là hai cơ chế bảo mật quan trọng, nhưng phạm vi bảo vệ của chúng nằm hoàn toàn trong luồng uỷ quyền, không mở rộng đến ngữ cảnh thiết bị nơi luồng đó diễn ra.

state là một giá trị ngẫu nhiên được gửi kèm yêu cầu uỷ quyền và được kiểm tra lại ở callback, nhằm liên kết phản hồi với phiên trình duyệt đã khởi tạo yêu cầu. Đây là biện pháp chống CSRF cổ điển trong OAuth: nó ngăn kẻ tấn công chèn một mã uỷ quyền của mình vào phản hồi mà nạn nhân nhận được. PKCE, với cặp code_verifier/code_challenge, bảo vệ mã uỷ quyền khỏi bị đánh chặn và sử dụng lại: kẻ tấn công có được mã nhưng không có verifier sẽ không thể đổi lấy token.

Cả hai đều hoạt động ở tầng toàn vẹn và ràng buộc phiên uỷ quyền. Chúng trả lời câu hỏi: "Phản hồi này có thuộc về yêu cầu mà client này đã khởi tạo không?" Chúng không trả lời câu hỏi mà nền tảng thực sự quan tâm khi đánh giá rủi ro: "Yêu cầu uỷ quyền này đến từ cùng một thực thể thiết bị với các tài khoản đã uỷ quyền trước đó không?"

Điểm mấu chốt nằm ở chỗ: một luồng OAuth hoàn toàn hợp lệ về mặt giao thức, state khớp, PKCE được xác minh đúng, vẫn có thể bị nền tảng gắn cờ nếu ngữ cảnh thiết bị của nó trùng khớp với các tài khoản khác. Giao thức OAuth không có khái niệm "thiết bị" theo nghĩa mà hệ thống chống lạm dụng của nền tảng đang vận hành. Nó không thu thập fingerprint, không đọc cookie của bên thứ ba, không so sánh IP. Kỳ vọng state và PKCE giải quyết vấn đề đa tài khoản là một sự nhầm lẫn tầng: hai cơ chế này đang làm đúng việc của chúng, chỉ là việc đó không liên quan đến nguyên nhân kích hoạt xác minh.

Những gì nền tảng thực sự "nhìn thấy" ở bước callback

Ở thời điểm người dùng hoàn tất uỷ quyền và được chuyển hướng trở lại ứng dụng, trình duyệt đã mang theo một lượng lớn tín hiệu mà giao thức OAuth không kiểm soát. Các nền tảng lớn kết hợp nhiều lớp tín hiệu để đưa ra phán đoán về "cùng một ngữ cảnh vận hành".

Lớp thứ nhất là fingerprint thiết bị. Các tham số như Canvas rendering, WebGL renderer, AudioContext fingerprint, danh sách font, độ phân giải màn hình và múi giờ được thu thập và băm thành một định danh ổn định tương đối. Trong các hệ thống chống lạm dụng, "nhiều tài khoản xuất phát từ cùng một fingerprint" là một tín hiệu rủi ro độc lập, thường được gán trọng số đáng kể trong mô hình tính điểm. Một fingerprint không nhất thiết phải duy nhất tuyệt đối để có giá trị: chỉ cần nó ổn định và tái xuất hiện cùng với các tài khoản khác là đủ để tạo ra một liên kết.

Lớp thứ hai là trạng thái lưu trữ trên trình duyệt. Đây là yếu tố thường bị đánh giá thấp. Các nền tảng không chỉ dựa vào cookie phiên đăng nhập; chúng duy trì những định danh thiết bị tồn tại lâu hơn nhiều so với phiên làm việc. Facebook sử dụng cookie datr như một định danh gắn với trình duyệt, tồn tại kéo dài sau khi đăng xuất và có thể được dùng để liên kết hoạt động của các tài khoản khác nhau trên cùng một thiết bị. Google sử dụng NID (hoặc Secure-ENID), một cookie gắn với trình duyệt, lưu trữ tùy chọn người dùng và đóng vai trò định danh trình duyệt với thời hạn từ 6 đến 13 tháng kể từ lần sử dụng cuối. Nó không phải là một vân tay thiết bị duy nhất tuyệt đối, nhưng đủ ổn định để liên kết các hoạt động trên cùng một trình duyệt. Khi người dùng uỷ quyền tài khoản thứ hai trong cùng một profile trình duyệt, các định danh này đã tồn tại từ trước và gắn chặt với ngữ cảnh thiết bị mà tài khoản thứ nhất vừa đi qua.

Lớp thứ ba là tín hiệu mạng và hành vi. Cùng một địa chỉ IP hoặc cùng một dải ASN, đặc biệt khi các lần uỷ quyền diễn ra trong khoảng thời gian ngắn, củng cố thêm phán đoán rằng các tài khoản đang được vận hành từ cùng một điểm kiểm soát.

Điều đáng chú ý là các nền tảng không đưa ra quyết định dựa trên một tín hiệu đơn lẻ. Hệ thống đánh giá rủi ro kết hợp fingerprint, trạng thái lưu trữ, mạng và hành vi thành một đồ thị liên kết: tài khoản, thiết bị, IP và các tài sản khác là các nút; mỗi lần uỷ quyền tạo ra hoặc củng cố một cạnh. Khi đồ thị cho thấy nhiều tài khoản cùng nối vào một cụm thiết bị-mạng, biện pháp xử lý không nhất thiết nhắm vào từng tài khoản riêng lẻ, mà có thể lan sang toàn bộ cụm liên quan.

Đây là lý do vì sao "xóa cookie" hoặc "dùng chế độ ẩn danh" thường không giải quyết được vấn đề: fingerprint phần cứng và một số tín hiệu tầng thấp vẫn tồn tại, và ngay cả khi một lớp tín hiệu bị loại bỏ, các lớp khác vẫn có thể duy trì liên kết.

Vì sao "ẩn danh" không phải là câu trả lời kỹ thuật

Chế độ ẩn danh của trình duyệt được thiết kế để không lưu lịch sử cục bộ sau khi đóng phiên, nhưng nó không tạo ra một thiết bị mới. Canvas fingerprint, WebGL renderer, danh sách font và các đặc trưng phần cứng khác vẫn được tính từ cùng một máy. Các cơ chế lưu trữ cấp thấp hơn như supercookie hoặc định danh được đồng bộ qua các kênh khác cũng có thể vượt qua ranh giới profile. Nói cách khác, ẩn danh giải quyết một phần của lớp lưu trữ phiên, nhưng không thay đổi lớp định danh thiết bị. Trong mô hình đánh giá đa tín hiệu, việc loại bỏ một lớp không làm biến mất phán đoán nếu các lớp còn lại vẫn đủ mạnh để duy trì liên kết.

Đây cũng là lý do vì sao các giải pháp được quảng cáo là "tách biệt môi trường" bằng proxy và profile riêng lẻ thường không đáng tin cậy trong bối cảnh tuân thủ: chúng cố gắng làm biến mất tín hiệu, trong khi bản chất của vấn đề là mối quan hệ giữa các tài khoản đã được thiết lập qua hành vi uỷ quyền tuần tự. Một ví dụ cụ thể của hướng tiếp cận này là các trình duyệt vân tay như BitBrowser: công cụ cho phép tạo nhiều profile độc lập, mỗi profile đi kèm proxy riêng và các tham số fingerprint (Canvas, WebGL, danh sách font) được ngẫu nhiên hóa để trông khác nhau. Về mặt kỹ thuật, các công cụ này xử lý được cả ba lớp tín hiệu mà bài viết vừa liệt kê: fingerprint, trạng thái lưu trữ và mạng. Điểm mà chúng không với tới là bản chất vấn đề: hành vi một người vận hành lần lượt uỷ quyền nhiều tài khoản vẫn để lại một mẫu tuần tự mà hệ thống chống lạm dụng nhận diện được từ phía hành vi, chứ không phải từ phía thiết bị. Việc cố tình làm sai lệch tín hiệu thiết bị để che giấu mối quan hệ giữa các tài khoản, dù khả thi về mặt kỹ thuật, vẫn nằm ngoài phạm vi của một kiến trúc tuân thủ.

Nguyên tắc thiết kế: tách biệt tài sản thay vì che giấu thiết bị

Nếu vấn đề không thể giải quyết ở tầng giao thức OAuth và không nên giải quyết bằng cách làm biến dạng tín hiệu thiết bị, thì hướng đi đúng là thay đổi mô hình uỷ quyền để giảm sự phụ thuộc vào hành vi "đăng nhập tuần tự nhiều tài khoản trên cùng một trình duyệt".

Các nền tảng lớn đều cung cấp cơ chế uỷ quyền dựa trên tài sản thay vì dựa trên danh tính cá nhân. Với Meta, Partner Access trong Business Portfolio cho phép một agency nhận quyền quản lý Page, ad account hoặc Instagram account của khách hàng thông qua ID doanh nghiệp, mà không cần chia sẻ mật khẩu hay đăng nhập vào tài khoản cá nhân của khách. Quyền này có thể bị thu hồi bất kỳ lúc nào, và agency tự quản lý đội ngũ của mình bên trong quyền truy cập đó. Google Brand Account cho phép nhiều người dùng quản lý cùng một tài sản thương hiệu thông qua tài khoản Google riêng của họ, với các vai trò được phân biệt rõ ràng.

Điểm chung của các mô hình này là chúng không yêu cầu người vận hành phải lần lượt đăng nhập vào từng tài khoản khách hàng trong cùng một phiên trình duyệt. Quyền được cấp ở cấp tài sản, không phải ở cấp phiên đăng nhập cá nhân. Từ góc độ tín hiệu thiết bị, điều này làm giảm đáng kể sự hình thành của mô hình "nhiều tài khoản tuần tự từ một thiết bị": không phải vì tín hiệu bị che giấu, mà vì hành vi tạo ra tín hiệu đó không còn cần thiết.

Các công cụ như Hootsuite hay Buffer vận hành được ở quy mô lớn một phần vì chúng xuất bản nội dung qua API chính thức của nền tảng, đúng với cách nền tảng kỳ vọng một ứng dụng bên thứ ba hoạt động. Việc uỷ quyền qua API chính thức, với các scope được định nghĩa và giới hạn, tạo ra một kênh vận hành có thể kiểm chứng và có thể thu hồi, khác về bản chất so với việc mô phỏng hành vi đăng nhập của người dùng cuối trên trình duyệt.

Kết luận

Vấn đề "tài khoản thứ hai kích hoạt xác minh" không phải là lỗi của state hay PKCE, và không thể được giải quyết bằng cách tinh chỉnh luồng OAuth. Nguyên nhân nằm ở chỗ giao thức OAuth vận hành ở một tầng khác với hệ thống đánh giá rủi ro thiết bị của nền tảng. state và PKCE bảo vệ tính toàn vẹn của yêu cầu uỷ quyền; chúng không và không thể bảo vệ ngữ cảnh thiết bị mà yêu cầu đó được thực thi.

Đối với một công cụ quản lý đa tài khoản, hệ quả thiết kế là: đừng cố gắng làm cho các tài khoản trông như đến từ các thiết bị khác nhau. Thay vào đó, hãy thiết kế kiến trúc uỷ quyền dựa trên tài sản và API chính thức, nơi quyền được cấp ở cấp tài nguyên, có thể kiểm toán và thu hồi, và không phụ thuộc vào việc người vận hành lần lượt đi qua nhiều phiên đăng nhập cá nhân trên cùng một môi trường trình duyệt. Đó không phải là một giải pháp "vượt qua" cơ chế phát hiện; đó là cách duy nhất để xây dựng một kiến trúc không tạo ra mẫu hành vi mà cơ chế đó được thiết kế để phát hiện.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí