Bug bảo mật và góc nhìn từ nhiều phía
Sumary
Trong bài viết này, mình sẽ chia sẻ về một lỗ hổng thú vị "Đổi Mật Khẩu Không Cần Xác Thực Mật Khẩu Cũ," dẫn đến nguy cơ chiếm đoạt tài khoản và khóa trái phép người dùng. Ban đầu, lỗ hổng bị đánh giá thấp và suýt chút nữa bị từ chối, nhưng nhờ sự kiên trì, mình đã thuyết phục được đội ngũ an ninh, giúp lỗ hổng được chấp nhận và nhận về bounty. Hãy cùng xem hành trình đầy "drama" này diễn ra như thế nào nhé!
Chi tiết
1. Tự đánh giá
Mức độ nghiêm trọng: Thấp đến Trung Bình
Lại là mình đây, trong cuộc săn bug gần đây, mình đã tìm ra một lỗ hổng khá thú vị: "Password Change without Current Password Validation." Đây là một lỗ hổng bảo mật nghiêm trọng vì hệ thống cho phép người dùng thay đổi mật khẩu mà không cần nhập mật khẩu cũ. Điều này tạo cơ hội cho kẻ tấn công chiếm quyền truy cập tài khoản của người dùng nếu họ có được token phiên. Và rất may là khi nghía qua endpoint này, đây lại là lỗi cuối cùng mình đặt niềm tin vào, vì quá ít chức năng, mà ngỡ như rằng chắc không còn lỗi gì đâu!
Tình cờ khi nhìn vào việc chỉnh sửa thông tin người dùng, mình thấy có chức năng thay đổi thông tin password. Và mình suy nghĩ, nếu không nhập pass cũ ở request thay vì ở trên FE thì có được không nhỉ? Và mình thực hiện ngay cho nóng!
Lỗ hổng này thuộc loại "Missing Authentication for Critical Function" và cho phép thay đổi mật khẩu mà không cần xác thực mật khẩu cũ. Điều này vi phạm nguyên tắc bảo mật khi luồng nghiệp vụ bị sai, và không đảm bảo sự toàn vẹn của hệ thống.
2. Nhận diện và báo cáo
Ở bước đầu, mình thử xoá 1 ký tự trong current_password, send request đi và bùmmmm, hệ thống trả về status 200. Mạnh tay hơn, mình xoá hẳn giá trị của current_password. Hệ thống không hề yêu cầu nhập current_password khi thay đổi mật khẩu!!! Kẻ tấn công có thể đổi mật khẩu mà không cần biết mật khẩu cũ, dễ dàng chiếm quyền kiểm soát tài khoản của người dùng.
Các Bước Khai Thác Lỗ Hổng:
-
Xác thực với tư cách là một người dùng hợp lệ và bắt lại yêu cầu khi cố gắng thay đổi mật khẩu.
-
Sửa yêu cầu để cập nhật mật khẩu mà không cung cấp current_password. Có thể đặt current_password thành một chuỗi trống.
Ví dụ yêu cầu:
PATCH /v3/users/me HTTP/2
Host: redacted.com
Authorization: Bearer token
Content-Type: application/json
Content-Length: 96
{ "current_password": "", "password": "Sup3rStr0ngP@ss", "password_confirmation": "Sup3rStr0ngP@ss" }
Quan sát phản hồi từ máy chủ, thấy rằng yêu cầu được xử lý thành công và mật khẩu được thay đổi mà không cần xác minh mật khẩu hiện tại.
Tác Động
-
Chiếm Đoạt Tài Khoản (Account Takeover): Kẻ tấn công có token phiên hoặc khóa xác thực có thể dễ dàng thay đổi mật khẩu và kiểm soát tài khoản của người dùng.
-
Từ Chối Dịch Vụ (Denial of Service): Khi mật khẩu bị thay đổi mà không cần biết mật khẩu cũ, người dùng hợp pháp có thể bị khóa khỏi tài khoản của họ.
-
Rủi Ro Bảo Mật: Tài khoản của người dùng dễ bị tấn công và có thể dẫn đến rò rỉ thông tin nhạy cảm.
3. Hướng nhìn từ triager
Câu Chuyện Nhận Bounty Ly Kỳ
Lúc đầu, khi mình gửi báo cáo, phản hồi từ triager có vẻ không mấy khả quan. Họ cho rằng đây không phải là một lỗi bảo mật và có thể chỉ là một lỗi nhỏ trong thiết kế. Dưới đây là phần "drama" đã diễn ra giữa mình và đội triage:
-
Ngày 25/10: Người kiểm duyệt ban đầu không xem đây là một nguy cơ bảo mật do kẻ tấn công cần có quyền truy cập vào token người dùng. Tuy nhiên, họ khuyến khích thử nghiệm thêm, đặc biệt là tìm cách liên kết với CSRF hoặc các lỗi khác để tăng tác động bảo mật.
-
Ngày 28/10: Sau vài lần phản hồi, người kiểm duyệt đánh giá báo cáo chỉ ở mức “Informative” do không đủ chứng minh mức độ nghiêm trọng. Tuy nhiên, họ mở lại báo cáo để chờ xem liệu có thể liên kết thêm với các lỗ hổng khác không.
-
Ngày 29/10: Sau khi nhận giải thích chi tiết từ mình về nguy cơ chiếm quyền tài khoản và khả năng tấn công liên kết, người kiểm duyệt đổi trạng thái sang “Triage” và chuyển báo cáo đến công ty chính để xem xét.
-
Ngày 3/11: Cuối cùng, công ty thông qua báo cáo với mức độ nghiêm trọng “Low” và chấp nhận trả bounty, và cảm ơn mình vì đóng góp giá trị của mình cho an ninh hệ thống của công ty.
Kết Quả
Vậy là báo cáo của mình không chỉ được accept mà còn nhận được bounty! Cuối cùng mình đã thành công và được thưởng bounty cho phát hiện này. Đây là minh chứng cho việc kiên trì trong bug bounty – đôi khi bạn phải vượt qua nghi ngờ ban đầu và tiếp tục bảo vệ quan điểm của mình!
Kết Luận
Lỗ hổng không yêu cầu xác thực mật khẩu cũ là một lỗi phổ biến nhưng nghiêm trọng, dễ dẫn đến chiếm đoạt tài khoản. Mình hy vọng chia sẻ này sẽ giúp ích cho các bạn khi săn bug và đối mặt với những tình huống tương tự trong quá trình làm việc với các triager. Hãy luôn kiên trì và bảo vệ quan điểm của mình nếu tin rằng đó là một lỗi thực sự!
Bounus: Thừa thắng xông lên, thì theo logic trang web yêu cầu khi thay đổi mail cũng cần phải điền mật khẩu (mail là định danh để có thể đăng nhập). Mình cũng thử tương tự như trên và họ cũng chấp nhận lỗi! Quá tuyệt vời!!!
Cảm ơn mọi người đã đọc!
All rights reserved