# lý thuyết ## Authentication ### Tìm hiểu các cơ chế xác thực sau: HTTP basic authentication, HTTP digest authentication. Hai cơ chế xác thực trên có vấn đề gì về security? Basic Auth là cơ chế xác thực đơn giản nhất của một ứng dụng web. Cách hoạt động của Basic Auth là gửi chính username + password của người dùng theo mỗi request hoặc username+password đã được encode(ví dụ: base64). ![image](https://hackmd.io/_uploads/HkSVfIpFp.png) Digest Auth có cơ chế hoạt động tương tự, tuy nhiên thông tin được gửi đi dưới dạng hash thay vì thông tin bản rõ hoặc đã được encode có thể dễ dàng phục hồi. Về vấn đề bảo mật, Basic auth nếu không được sử dụng cùng với TLS sẽ dẫn đến lộ credentials trong quá trình gửi gói tin nếu bị chặn bắt. credentials cũng có thể bị lộ nếu attacker tìm cách lấy được access log. Ngoài ra, Basic auth không cung cấp cơ chế để thực hiện logout. Trong các trình duyệt hiện đại, credentials được lưu trong bộ nhớ đệm để xác thực cơ bản thường bị xóa khi xóa lịch sử duyệt web. Với Digest Auth cũng sẽ gặp vấn đề tương tự, tuy nhiên thông tin đã được hash nên kẻ tấn công sẽ gặp khó khăn để phục hồi thông tin. Một giá trị `nonce` được sử dụng thêm vào với credentials khi hash, để phòng tránh `replay attack`. Digest Auth không cung cấp cơ chế nào để client xác minh danh tính của máy chủ. Man-in-the-middle attacker có thể yêu cầu client dùng basic authen thay vì Digest authen. Việc dùng Digest Auth dẫn đến việc lưu trữ mật khẩu trên server không thể dùng các hàm hash, do yêu cầu các thông tin phải có khả năng được phục hồi. ``` HA1 = MD5(username:realm:password) HA2 = MD5(method:digestURI) response = MD5(HA1:nonce:HA2) ``` => Lộ HA1 cũng sẽ dẫn đến attacker có thể truy cập dễ dàng. ![image](https://hackmd.io/_uploads/BkkstLpK6.png) ### Liệt kê một số kĩ thuật (lỗ hổng) bypass authentication khi ứng dụng sử dụng Oauth2. * Client site * Improper implementation of the implicit grant type: Với implicit grant, `access_token` được gửi từ authorization service đến client application thông qua trình duyệt của người dùng dưới dạng một đoạn URL. Sau đó, client application sẽ truy cập token bằng cách sử dụng javascript. Vấn đề là, nếu ứng dụng muốn duy trì phiên sau khi người dùng đóng trang, nó cần lưu trữ dữ liệu người dùng hiện tại (thường là user_id và access_token) ở đâu đó. Để giải quyết vấn đề này, client application sẽ gửi dữ liệu này đến máy chủ theo yêu cầu POST và sau đó gán cho người dùng một cookie session. Request này gần tương tự với submit form request của một đăng nhập dựa trên mật khẩu. Tuy nhiên, trong trường hợp này, máy chủ không có bất kỳ secret key hoặc mật khẩu nào để so sánh với dữ liệu đã gửi, điều đó có nghĩa là nó hoàn toàn được tin cậy. Do đó, hành vi này có thể dẫn đến lỗ hổng nghiêm trọng nếu ứng dụng khách không kiểm tra chính xác xem access_token có khớp với dữ liệu khác trong yêu cầu hay không. Trong trường hợp này, kẻ tấn công có thể chỉ cần thay đổi các tham số được gửi đến máy chủ để mạo danh bất kỳ người dùng nào. * Improper handling of state parameter: Nếu tham số State: bị thiếu, giá trị cố định, có nhưng ko được xác thực. OAuth 2.0 có thể dễ bị tấn công bởi CSRF. Để khai thác, thực hiện quá trình ủy quyền trong tài khoản của bạn và tạm dừng ngay sau khi ủy quyền. Sau đó gửi URL này cho nạn nhân đã đăng nhập, họ sẽ thêm tài khoản của bạn vào tài khoản của họ(ví dụ chức năng`liên kết tài khoản mạng xã hội`). * Disclosure of secrets: ![image](https://hackmd.io/_uploads/BkzMfMRtT.png) Các tham số OAuth 2.0 private có thể bị leak. Ví dụ: nếu request của Authorization Code Grant để lấy cho access_token (bước 5) được thực thi từ browser, thay vì máy client application. * Missing validation in redirect_uri leads to `access token` takeover: Tham số `redirect_uri` trong quy trinhf OAuth2 workflow được máy chủ ủy quyền sử dụng làm vị trí hoặc địa chỉ để phân phối `access_token` hoặc `auth_code` bằng cách chuyển hướng trình duyệt. Trong dưới đây ![image](https://hackmd.io/_uploads/BJvX-m0KT.png) tham số `redirect_uri` được client application khởi tạo như một phần của request tới máy chủ ủy quyền ở bước 2 khi người dùng web nhấp vào nút đăng nhập. Sau khi máy chủ ủy quyền xác thực thông tin xác thực (bước 6), nó sẽ gửi lại `auth_token` (hoặc `access_token` đối với `implicit grant`) dưới dạng tham số cho `redirect_uri` được sử dụng trong bước 2. Nếu attacker có thể trigger nạn nhân gửi yêu cầu đến máy chủ ủy quyền có `redirect_uri` do kẻ tấn công kiểm soát và máy chủ ủy quyền KHÔNG xác thực `redirect_uri`, thì `access_token` sẽ được gửi đến URI do kẻ tấn công kiểm soát * Pre-account takeover: xảy ra khi đáp ứng hai điều kiện sau: 1. Client application hỗ trợ nhiều phương thức xác thực, sử dụng thông tin đăng nhập bằng mật khẩu và dịch vụ của bên thứ ba (như Facebook hoặc Google) làm nhà cung cấp xác thực OAuth. 2. Client application hoặc dịch vụ bên thứ ba không thực hiện xác minh email trong quá trình đăng ký. Dẫn đến: 1. Kẻ tấn công tạo một tài khoản với địa chỉ email của nạn nhân và mật khẩu của kẻ tấn công trước khi nạn nhân đăng ký trên ứng dụng. 2. Sau đó, nạn nhân đăng nhập thông qua dịch vụ của bên thứ ba, như Google hoặc Facebook. 3. Nạn nhân thực hiện một số hoạt động ứng dụng. Ứng dụng sẽ lưu những hành động này và có thể sẽ sử dụng địa chỉ email làm mã định danh cho người dùng trong cơ sở dữ liệu. 4. Giờ đây, kẻ tấn công có thể đăng nhập với tư cách nạn nhân và đọc dữ liệu do nạn nhân thêm vào bằng cách sử dụng địa chỉ email của nạn nhân và mật khẩu của kẻ tấn công đã tạo ở bước 1. * OAuth2 access_token is leaked through referrer header: [https://hackerone.com/reports/202781](https://) * Flawed scope validation * Scope upgrade(Authorization Code Grant): Với Authorization Code Grant, dữ liệu của người dùng được yêu cầu và gửi qua kênh an toàn server-to-server mà kẻ tấn công hoặc bên thứ ba thường không thể can thiệp. Tuy nhiên, vẫn có thể đạt được kết quả tương tự bằng cách đăng ký client application của riêng họ với dịch vụ ủy quyền. Ví dụ: giả sử application client của kẻ tấn công ban đầu yêu cầu quyền truy cập vào địa chỉ email của người dùng bằng `scope` read:email. Sau khi người dùng chấp thuận yêu cầu này, application client sẽ nhận được mã ủy quyền. Khi kẻ tấn công kiểm soát client của chúng, chúng có thể thêm một tham số `scope` khác vào yêu cầu trao đổi mã có chứa `scope profile`: ```request POST /oauth/access_token HTTP/1.1 Host: auth-server.com Contetn-Type: application/json Content-Length: 191 { "client_id": "application_client_id", "client_secret": "application_client_secret", "grant_type": "authorization_code", "code": "a68YhewbiYl93TR89hdjYwqP0", "scope": "read:email%20read:user" } ``` * Scope upgrade(Implicit Grant): Đối với Implicit Grant, `access_token` được gửi qua trình duyệt, có nghĩa là kẻ tấn công có thể đánh cắp `token` được liên kết với các ứng dụng và sử dụng chúng trực tiếp. Sau khi đánh cắp `access_token`, họ có thể gửi các browser-based request đến OAuth service's /userinfo endpoint, thêm thông số `scope` mới vào theo cách thủ công. Lý tưởng nhất là dịch vụ OAuth nên xác thực giá trị `scope` này dựa trên giá trị đã được sử dụng khi tạo `token`, nhưng điều này không phải lúc nào cũng đúng. Miễn là các quyền đã điều chỉnh không vượt quá mức truy cập được cấp trước đó cho ứng dụng này, kẻ tấn công có thể truy cập vào dữ liệu bổ sung mà không cần người dùng phê duyệt thêm. ### Liệt kê một số kĩ thuật (lỗ hổng) bypass 2FA. * Token dựa trên "something you have", có thể được gửi qua email hoặc sms => Phising attack lừa người dùng cung cấp token, chặn bắt đường truyền. * Đôi khi, việc triển khai xác thực hai yếu tố có sai sót đến mức có thể bỏ qua hoàn toàn. Nếu người dùng được nhắc nhập mật khẩu lần đầu tiên, sau đó được nhắc nhập mã xác minh trên một trang riêng, thì người dùng thực sự ở trạng thái "logged in" trước khi họ nhập mã xác minh. Trong trường hợp này, bạn nên kiểm tra xem liệu bạn có thể trực tiếp chuyển sang trang "logged-in only" sau khi hoàn thành bước xác thực đầu tiên hay không. Đôi khi, bạn sẽ thấy rằng một trang web không thực sự kiểm tra xem bạn có hoàn thành bước thứ hai trước khi tải trang hay không. * Đôi khi logic thiếu sót trong xác thực hai yếu tố có nghĩa là sau khi người dùng hoàn thành bước đăng nhập ban đầu, trang web không xác minh đầy đủ rằng chính người dùng đó đang hoàn thành bước thứ hai. Ví dụ: người dùng đăng nhập bằng thông tin đăng nhập thông thường của họ ở bước đầu tiên như sau: ```request POST /login-steps/first HTTP/1.1 Host: vulnerable-website.com ... username=carlos&password=qwerty ``` Sau đó, họ được chỉ định một cookie liên quan đến tài khoản của họ trước khi được chuyển sang bước thứ hai của quy trình đăng nhập: ```request HTTP/1.1 200 OK Set-Cookie: account=carlos GET /login-steps/second HTTP/1.1 Cookie: account=carlos ``` Khi gửi mã xác minh, request sẽ sử dụng cookie này để xác định tài khoản nào người dùng đang cố truy cập ```request POST /login-steps/second HTTP/1.1 Host: vulnerable-website.com Cookie: account=carlos ... verification-code=123456 ``` Trong trường hợp này, kẻ tấn công có thể đăng nhập bằng thông tin đăng nhập của riêng họ nhưng sau đó thay đổi giá trị của cookie tài khoản thành bất kỳ tên người dùng tùy ý nào khi gửi mã xác minh. ```request POST /login-steps/second HTTP/1.1 Host: vulnerable-website.com Cookie: account=victim-user ... verification-code=123456 ``` * Cũng như mật khẩu, các trang web cần thực hiện các bước để ngăn chặn việc bruteforce mã xác minh 2FA. Điều này đặc biệt quan trọng vì mã thường là số đơn giản có 4 hoặc 6 chữ số. Nếu không có sự bảo vệ mạnh mẽ đầy đủ thì việc bẻ khóa một mã như vậy là chuyện nhỏ. Một số trang web cố gắng ngăn chặn điều này bằng cách tự động đăng xuất người dùng nếu họ nhập một số mã xác minh không chính xác. Điều này không hiệu quả trong thực tế vì kẻ tấn công nâng cao thậm chí có thể tự động hóa quy trình. * Sử dụng chức năng reset pass: một số trang cho phép đăng nhập trực tiếp sau khi quên mật khẩu hoặc reset password. * Kiểm tra xem bạn có thể nhận được mã thông báo từ tài khoản của mình hay không và thử sử dụng nó để vượt qua 2FA trong một tài khoản khác. (Sharing unused tokens) ## Access control ### Vertical access control Là các cơ chế hạn chế quyền truy cập vào chức năng nhạy cảm đối với những loại người dùng cụ thể. Với Vertical access control, các loại người dùng khác nhau có quyền truy cập vào các chức năng ứng dụng khác nhau. Ví dụ: quản trị viên có thể sửa đổi hoặc xóa bất kỳ tài khoản nào của người dùng, trong khi người dùng thông thường không có quyền truy cập vào các hành động này. ### Horizontal access controls Là các cơ chế hạn chế quyền truy cập vào tài nguyên đối với những người dùng cụ thể. Với các điều khiển truy cập theo chiều ngang, những người dùng khác nhau có quyền truy cập vào một tập hợp con các tài nguyên cùng loại. Ví dụ: một ứng dụng ngân hàng sẽ cho phép người dùng xem các giao dịch và thực hiện thanh toán từ tài khoản của chính họ chứ không phải tài khoản của bất kỳ người dùng nào khác. ### IDOR là gì? là một lỗ hổng phát sinh khi kẻ tấn công có thể truy cập hoặc sửa đổi các đối tượng bằng cách thay đổi các mã định danh được sử dụng trong URL hoặc tham số của ứng dụng web. Điều này xảy ra do thiếu access control check, không xác minh được liệu người dùng có được phép truy cập dữ liệu cụ thể hay không. #### Ví dụ: khi người dùng truy cập hồ sơ của họ, ứng dụng có thể tạo một URL như thế này: ``` https://example.org/users/123 ``` Số 123 trong URL là tham chiếu trực tiếp đến bản ghi của người dùng trong cơ sở dữ liệu, thường được biểu thị bằng khóa chính. Nếu kẻ tấn công thay đổi con số này thành 124 và có quyền truy cập vào thông tin của người dùng khác, ứng dụng sẽ chứa lỗ hổng IDOR. Điều này xảy ra do ứng dụng không kiểm tra chính xác xem người dùng có được phép xem dữ liệu của người dùng 124 hay không trước khi hiển thị dữ liệu đó. ### Làm thế nào để kiểm tra một chức năng có bị IDOR không? * Xác định các điểm có thể xảy ra IDOR. * Đánh giá các biện pháp kiểm soát truy cập và liệu chúng có dễ bị IDOR tấn công hay không Dưới đây là một số tình huống điển hình cho lỗ hổng này và các phương pháp kiểm tra từng lỗ hổng: #### The Value of a Parameter Is Used Directly to Retrieve a Database Record Sample request: ```url http://foo.bar/somepage?invoice=12345 ``` Trong trường hợp này, giá trị của tham số `invoice` được sử dụng làm chỉ mục trong bảng `invoice` trong cơ sở dữ liệu. Ứng dụng lấy giá trị của tham số này và sử dụng nó trong truy vấn cơ sở dữ liệu. Sau đó ứng dụng sẽ trả về thông tin hóa đơn cho người dùng. Vì giá trị của hóa đơn được đưa trực tiếp vào truy vấn nên bằng cách sửa đổi giá trị của tham số, bạn có thể truy xuất bất kỳ đối tượng hóa đơn nào, bất kể hóa đơn thuộc về người dùng nào. Để kiểm tra trường hợp này, người kiểm tra phải lấy mã định danh của hóa đơn thuộc về một người dùng thử nghiệm khác, sau đó kiểm tra xem liệu có thể truy cập các đối tượng mà không được phép hay không. #### The Value of a Parameter Is Used Directly to Perform an Operation in the System ```url http://foo.bar/changepassword?user=someuser ``` Trong trường hợp này, giá trị của tham số `user` được sử dụng để báo cho ứng dụng biết người dùng nào nên thay đổi mật khẩu. Trong nhiều trường hợp, bước này sẽ là một phần của thao tác gồm nhiều bước. Ở bước đầu tiên, ứng dụng sẽ nhận được yêu cầu cho biết mật khẩu của người dùng nào sẽ được thay đổi và trong bước tiếp theo, người dùng sẽ cung cấp mật khẩu mới (không yêu cầu mật khẩu hiện tại). tham số `user` được sử dụng để tham chiếu trực tiếp đối tượng của người dùng mà thao tác thay đổi mật khẩu sẽ được thực hiện. Để kiểm tra trường hợp này, người kiểm tra nên cố gắng cung cấp tên người dùng kiểm tra khác với tên người dùng hiện đang đăng nhập và kiểm tra xem liệu có thể sửa đổi mật khẩu của người dùng khác hay không. #### The Value of a Parameter Is Used Directly to Retrieve a File System Resource ```url http://foo.bar/showImage?img=img00011 ``` Trong trường hợp này, giá trị của tham số `img` được sử dụng để cho ứng dụng biết người dùng định truy xuất tệp nào. Bằng cách cung cấp tên hoặc mã định danh của một tệp khác (ví dụ: file=image00012.jpg), kẻ tấn công sẽ có thể truy xuất các đối tượng thuộc về người dùng khác. Để kiểm tra trường hợp này, người kiểm tra phải lấy một tham chiếu mà người dùng không được phép truy cập và cố gắng truy cập nó bằng cách sử dụng nó làm giá trị của tham số tệp. Lưu ý: Lỗ hổng này thường bị khai thác cùng với lỗ hổng directory/path traversal #### The Value of a Parameter Is Used Directly to Access Application Functionality ``` http://foo.bar/accessPage?menuitem=12 ``` same với các trường hợp trên, tham số menuitem thể hiện chắc năng/ menu được sử dụng với người dùng.