Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Self-XSS in Facebook payments flow leads to Instagram and Facebook account takeovers- 1867

ysammPosted 1 Month Ago
  • Facebook's payments and billing flows use third-party financial services providers. To perform these bank payments, Facebook embeds external services via iFrames that perform cross-window communication.
  • One integration that exists is the ACH Direct Debt flow; this embeds a third-party iframe into m.facebook.com with strict origin verification. The cross-window message-handling mechanism allows direct HTML injection, which is assumed to be safe because it's from a trusted domain. The reality is that all messages originating from this domain were trustworthy. Practically, origin validation is only as strong as the security of the trusted origin.
  • The handler for direct_debit_ach_initialization's learnMore event injects HTML directly into the DOM. This creates an XSS opportunity, if we can find more bugs. On one of the third-party providers, they found code that loads a remote configuration file via a URL and calls eval() on the cmd parameter.
  • Since we can control a message from the third-party domain, we can communicate with Facebook to trigger the XSS sink. All it takes is a postMessage from the iFrame and we have XSS in Facebook! This is actually self-XSS because the endpoint has a nonce that is not guessable. So, how is this useful?
  • With XSS on the page, it's possible to initiate the OAuth flow. By reading the iframe of the page with the OAuth flow for the user, it's possible to extract the OAuth codes from location.href of the iframe and compromise the account.
  • Here's the full exploit chain:
    1. Login CSRF is used to get a valid account setup.
    2. Attacker loads the ACH page with the vulnerable third-party provider.
    3. XSS is triggered on the third party iframe that calls postMessage to get XSS on Facebook.
    4. Attacker initializes the OAuth flow in an iFrame to steal the OAuth codes.
  • By itself, the XSS isn't bad enough to warrant an account takeover. So, they found some quirks to make this possible via the Save Login and the ability to keep a malicious page alive using Blob URL. Facebook has a GraphQL endpoint for account switching. With XSS on the site, this API can be called. By loading the payload via a Blob URL, Facebook cannot reload from the compromised execution context. So, the XSS remains persistent.
  • If there are no device-switchable accounts, there's an additional way. Trigger a Google OAuth flow for Facebook. Capture the authorization code after the redirect to Facebook and use it to link the attacker's account to theirs. This works without user interaction but requires that only one Google account is open in their browser.
  • To make the impact worse, third-party payment providers were able to execute arbitrary code within Facebook remotely. To target all users, it would have been simple for a threat actor to compromise these. After this bug, they were rewarded $62K. Great work!