Làm thế nào để giữ an toàn cho bí mật của người tiêu dùng OAuth và cách phản ứng khi nó bị xâm phạm?


79

Câu hỏi này xoay quanh việc cố gắng tìm hiểu các rủi ro bảo mật liên quan đến việc triển khai oauth trên nền tảng di động như Android. Giả định ở đây là chúng ta có một ứng dụng Android có mã khóa / bí mật của người tiêu dùng được nhúng vào.

Giả sử một bí mật của người tiêu dùng đã bị xâm phạm và một hacker đã nắm được nó, thì hậu quả của việc này là gì?

Các giả định về Bí mật
người tiêu dùng bị xâm phạm Tôi có đúng khi nói rằng bí mật của người tiêu dùng bị xâm phạm không ảnh hưởng đến bảo mật của người dùng hoặc bất kỳ dữ liệu nào được lưu trữ tại nhà cung cấp hỗ trợ OAuth mà người dùng đang tương tác. Bản thân dữ liệu không bị xâm phạm và hacker không thể lấy được.

Tin tặc sẽ cần có được mã thông báo truy cập người dùng hợp lệ và điều đó khó hơn rất nhiều.

Tin tặc có thể làm gì với bí mật của người tiêu dùng bị xâm phạm?
Tôi cũng đúng khi nêu những điều sau:

  • Tin tặc có thể thiết lập / xuất bản một ứng dụng bắt chước ứng dụng của tôi.
  • Tin tặc có thể thu hút người dùng đi qua luồng OAuth, lấy mã thông báo truy cập thông qua vũ điệu OAuth của tin tặc (sử dụng khóa / bí mật của người tiêu dùng bị xâm phạm).
  • Người dùng có thể nghĩ rằng anh ta đang giao dịch với ứng dụng của tôi, vì anh ta sẽ thấy một cái tên quen thuộc (khóa người dùng) trong quá trình ủy quyền.
  • Khi người tiêu dùng đưa ra yêu cầu thông qua tin tặc, tin tặc có thể dễ dàng đánh chặn mã thông báo truy cập và kết hợp với bí mật của người tiêu dùng giờ đây có thể thay mặt tôi ký yêu cầu để có quyền truy cập vào tài nguyên của tôi.

Tác động của người dùng cuối
Trong giả định rằng

  • một tin tặc đã thiết lập một ứng dụng / trang web sử dụng bí mật người tiêu dùng của tôi
  • một trong những người dùng của tôi đã bị lừa khi cấp quyền truy cập vào ứng dụng / trang web đó

Điều sau có thể xảy ra:

  • người dùng cuối có thể nhận thấy rằng có điều gì đó khó hiểu đang xảy ra và thông báo cho nhà cung cấp dịch vụ (ví dụ: Google) về ứng dụng độc hại
  • nhà cung cấp dịch vụ sau đó có thể thu hồi khóa / bí mật của người tiêu dùng

Tác động của người tiêu dùng OAuth (ứng dụng của tôi):
Ứng dụng của tôi (chứa bí mật của người tiêu dùng) sẽ cần được cập nhật, vì nếu không, tất cả khách hàng của tôi sẽ không thể ủy quyền cho ứng dụng của tôi thay mặt họ thực hiện các yêu cầu nữa (vì bí mật người tiêu dùng của tôi sẽ không còn có giá trị).

Ủy quyền tất cả lưu lượng truy cập OAuth
Mặc dù có thể ủy quyền rất nhiều tương tác OAuth thông qua một máy chủ web trung gian (thực hiện vũ điệu OAuth và gửi mã thông báo truy cập cho người dùng), người ta cũng sẽ phải ủy quyền tất cả các tương tác dịch vụ, vì khóa người dùng / bí mật được yêu cầu để ký mỗi yêu cầu. Đây có phải là cách duy nhất để giữ khóa / bí mật của người tiêu dùng bên ngoài ứng dụng dành cho thiết bị di động và được lưu trữ ở một nơi an toàn hơn trên máy chủ web trung gian không?

Các lựa chọn thay thế
Có các lựa chọn thay thế cho việc nhập proxy này không? Có thể lưu trữ bí mật của người tiêu dùng tại máy chủ web trung gian và có một số loại cơ chế mà ứng dụng Android (được xuất bản trên thị trường và đã được ký hợp lệ), có thể thực hiện một yêu cầu an toàn tới máy chủ web trung gian để lấy bí mật của người tiêu dùng và lưu trữ nó không trong ứng dụng? Có thể thực hiện một cơ chế mà máy chủ web trung gian "biết" rằng đây là một ứng dụng Android chính thức đang yêu cầu tìm nạp bí mật của người tiêu dùng và máy chủ web trung gian sẽ chỉ cung cấp bí mật của người tiêu dùng cho ứng dụng Android cụ thể đó không?

Câu trả lời:


53

Tóm tắt : Tôi chỉ chấp nhận rủi ro và giữ bí mật trong ứng dụng khách.

Thay thế máy chủ proxy :

Cách duy nhất bạn có thể giảm thiểu một cách hợp lý các vấn đề mà tôi liệt kê dưới đây và làm cho hoạt động của proxy, sẽ là đi hết chín thước - di chuyển tất cả logic nghiệp vụ để xử lý tài nguyên trên dịch vụ web của bên thứ ba sang máy chủ proxy của bạn, và làm cho ứng dụng khách trở nên ngu ngốc với giao diện người dùng phong phú. Bằng cách này, các hành động duy nhất mà ứng dụng độc hại có thể khiến proxy thực hiện thay mặt cho nó sẽ chỉ là những gì logic kinh doanh của bạn cần một cách hợp pháp.

Nhưng bây giờ bạn đang ở trong lĩnh vực của hàng loạt các vấn đề khác phải giải quyết về độ tin cậy và khả năng mở rộng.

Cân nhắc rất lâu về lý do tại sao proxy đơn giản không hoạt động :

Một số người, khi gặp sự cố, nghĩ rằng "Tôi biết, tôi sẽ thêm máy chủ proxy của riêng mình" Bây giờ họ gặp hai vấn đề. (gửi lời xin lỗi đến Jamie Zawinski)

Các giả định của bạn phần lớn là đúng. Ngay đến lúc bạn bắt đầu nghĩ về máy chủ của chính mình, liệu nó có giữ bí mật và ủy quyền các cuộc gọi cho ứng dụng khách hay nó cố gắng xác định xem ứng dụng có hợp pháp không và cung cấp bí mật cho nó. Trong cả hai cách tiếp cận, bạn vẫn phải giải quyết vấn đề "yêu cầu này có phải đến từ một đoạn mã tôi đã viết" không?

Để tôi nhắc lại - không có cách nào để phân biệt trên dây rằng phần mềm cụ thể đang chạy. Nếu dữ liệu trong tin nhắn có vẻ đúng, không có gì có thể chứng minh đó là một ứng dụng khác đang gửi tin nhắn đó .

Vào cuối ngày, nếu tôi đang viết một ứng dụng độc hại, tôi không quan tâm liệu mình có thực sự biết bí mật thực sự hay không, miễn là tôi có thể khiến ai đó biết nó thay mặt tôi. Vì vậy, nếu bạn cho rằng một ứng dụng độc hại có thể mạo danh ứng dụng của bạn với máy chủ OAuth của bên thứ ba, thì tại sao bạn chắc chắn rằng ứng dụng đó không thể mạo danh ứng dụng của bạn với proxy của bạn?

Nhưng xin chờ chút nữa. Miền nơi đặt dịch vụ proxy của bạn, là danh tính của bạn đối với cả khách hàng và nhà cung cấp OAuth (như được nhà cung cấp OAuth hiển thị cho người dùng cuối). Nếu một ứng dụng độc hại có thể khiến máy chủ của bạn thực hiện hành vi xấu, không chỉ khóa của bạn bị thu hồi mà danh tính web công khai của bạn cũng không còn đáng tin cậy nữa.


Tôi sẽ bắt đầu với điều hiển nhiên - không có cách nào để phân biệt trên dây rằng phần mềm cụ thể đang chạy. Nếu dữ liệu trong tin nhắn có vẻ đúng, không có gì có thể chứng minh đó là một ứng dụng khác đang gửi tin nhắn đó.

Do đó, bất kỳ thuật toán nào dựa vào bí mật được lưu trữ phía ứng dụng đều có thể bị giả mạo. Điểm mạnh của OAuth là nó không bao giờ cung cấp thông tin đăng nhập của người dùng cho ứng dụng, thay vào đó cấp cho ứng dụng thông tin đăng nhập tạm thời của chính nó mà người dùng có thể thu hồi nếu cần.

Tất nhiên, điểm yếu ở đây là một ứng dụng đủ tốt có thể khiến người dùng tin tưởng nó và không thu hồi các thông tin đăng nhập, trước khi nó hoàn thành các hành vi bất chính của mình.

Tuy nhiên, một cách để giảm thiểu điều này là cách tiếp cận của Google sử dụng OAuth 3 chân, thay vì 2 chân tiêu chuẩn. Trong OAuth 3 bên, không có bí mật được chỉ định trước, nhưng trên mỗi lần xác thực, một bí mật mã thông báo truy cập mới được cấp cùng với mỗi mã thông báo truy cập. Mặc dù cuối cùng điều này cũng có cùng một nhược điểm, vì một ứng dụng xấu có thể đọc bí mật mã thông báo của ứng dụng tốt từ quy trình của nó, điều này dẫn đến việc người dùng phải phê duyệt quyền truy cập ứng dụng mỗi khi nó cần mã thông báo truy cập mới.

Và tất nhiên, điều này cũng đồng nghĩa với việc nó sẽ gây bất tiện và khó chịu hơn cho người dùng.


Tôi đã chỉnh sửa câu hỏi một chút. Tôi muốn đảm bảo rằng những giả định mà tôi đang đưa ra trong câu hỏi là đúng. Tôi cũng không muốn tránh những bất tiện cho người dùng. Vì vậy, tôi thấy có 2 lựa chọn. 1. chỉ cần chấp nhận rủi ro, giữ bí mật trong mã và thực hiện một số xáo trộn. hoặc 2. thực hiện việc nhập proxy và giữ bí mật trên máy chủ web mà tôi khá chắc chắn rằng nó sẽ không bị xâm phạm. Đó có phải là một kết luận công bằng?
ddewaele

Tôi có một câu hỏi về điều này. Tại sao bạn nói không thể thấy rằng mã gọi là mã bạn đã viết. Bạn không thể chỉ gửi một số mã thông báo được liên kết với chữ ký ứng dụng của bạn mà đến lượt nó được liên kết với chứng chỉ của bạn. Chỉ các ứng dụng của bạn được ký bằng chứng chỉ của bạn và tệp này vẫn được giữ ở chế độ riêng tư.
Igor Čordaš

1
Ý tôi là, cho phép các cuộc gọi đến máy chủ proxy của bạn với giá trị bạn nhận được từ Chữ ký này [] sigs = context.getPackageManager (). GetPackageInfo (context.getPackageName (), PackageManager.GET_SIGNATURES) .signatures; for (Signature sig: sigs) {Trace.i ("MyApp", "Signature hashcode:" + sig.hashCode ()); }
Igor Čordaš

Và tại sao ứng dụng của tôi không thể chạy cùng mã đó mà thay vì context.getPackageInfo()mã cứng "com.your.app_name"?
Franci Penov

@FranciPenov Tôi nghĩ câu trả lời của bạn đang thiếu một phần quan trọng. Proxy tốt vì một lý do khác; họ có thể giảm phạm vi yêu cầu mà ai đó có thể thực hiện với bên thứ ba. Trong proxy của mình, bạn có thể xác định cuộc gọi nào đến bên thứ ba được phép.
Tijme,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.