https://example.com/?code=xxx&state=yyy Website need to ask provider to validate. Code can only be used once • id_token https://example.com/#id_token=eyJ… Signed info about user using public cert of provider
https://example.com/?code=xxx&state=yyy Website need to ask provider to validate. Code can only be used once • id_token https://example.com/#id_token=eyJ… Signed info about user using public cert of provider • token https://example.com/#access_token=xxx Token can be used with provider’s API
Query parameters sent to the website. Only allowed for response type code • Fragment https://example.com#access_token=xxx Does not end up in server logs, only reached by Javascript
Query parameters sent to the website. Only allowed for response type code • Fragment https://example.com#access_token=xxx Does not end up in server logs, only reached by Javascript • Web message postMessage({accessToken: 'xxx'}, 'https://example.com') Sent as a postMessage to the website
Query parameters sent to the website. Only allowed for response type code • Fragment https://example.com#access_token=xxx Does not end up in server logs, only reached by Javascript • Web message postMessage({accessToken: 'xxx'}, 'https://example.com') Sent as a postMessage to the website • Form post <form method=POST action=https://example.com>... A form that posts data back to the website
query parameters, including loading of images • XSS was even more common • Content Security Policy (CSP) did not exist • Large OAuth providers (like FB) made it easy to do wrong
to make sure the user that started the flow is the one finishing it • It’s the website’s responsibility to validate it • If validation fails, code is never sent back to provider
och 500 or similar • Redirect to start page • Redirect to login page • Redirect to login page with parameters removed • Redirect back to OAuth provider again
och 500 or similar • Redirect to start page • Redirect to login page • Redirect to login page with parameters removed • Redirect back to OAuth provider again My focus
gets transferred to sandbox/third-party • Sandbox has XSS • Two windows with same origin can reach each other • 2 days after my report, Youssef Sammouda made a similar finding on FB
clicks link, XSS in sandbox iframe 2. Opens popup, uses wrong response type XSS 3. Loads sandbox iframe, URL of main window is transferred 4. Sandbox XSS to sandbox on Reddit: frames[0].eval(..)
clicks link, XSS in sandbox iframe 5. Attacker got the token! 2. Opens popup, uses wrong response type XSS 3. Loads sandbox iframe, URL of main window is transferred 4. Sandbox XSS to sandbox on Reddit: frames[0].eval(..)
is sent somewhere else but we will try to get it • Such a fun bug, so many possibilities • There will be more alterations of this • Complex flow to explain, hang in there!
clicks link, loads chat widget 3. Opens popup, uses wrong response type 4. Loads sandbox iframe, current URL is transferred to Chat API 2. Loads chat widget, gets user’s API-token 4. Attacker polls API using token for current URL
clicks link, loads chat widget 5. Attacker got the token! 3. Opens popup, uses wrong response type 4. Loads sandbox iframe, current URL is transferred to Chat API 2. Loads chat widget, gets user’s API-token 4. Attacker polls API using token for current URL
on error pages involved in the OAuth-dance • Test the non-happy paths in OAuth yourself. Is GTM loaded in this flow? • OAuth-providers should allow turning off response- modes/types not being used