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!

More secure Facebook Canvas Part 2: More Account Takeovers- 1352

Youssef SammoudaPosted 2 Years Ago
  • Youssef specializes in finding vulnerabilities in clientside JavaScript code. Specifically, with Facebook integrations. In this article, he goes through a chain of issues that led to an account takeover but looking at the authentication process of Facebook Games.
  • When trying to authenticate using OAuth in this iFrame, there is some postMessage communication that occurs. Once this happens, a request to Facebook is made that pops up on a dialog box and returns back authentication information for the requesting application.
  • Of course, doing this as some security risk. So, they try to validate the redirect_uri and requesting origin. When getting the response from the Facebook OAuth endpoint, the redirect URI was the location for the postMessage sending origin. So, if you specified instagram, it would try to send the information to the instagram domain in the postMessage.
  • If the origin is null or undefined, then the value of "k" is set. This setting gets set automatically to the URL of the game application (aka iframe URL). Additionally, there is a check to verify that the app ID matches the URL for the postMessage is being sent to.
  • Since Youssef spends so much time at Meta, he knows everything about the authentication process. He knows that all Facebook apps have fbconnect://success as a valid redirect_uri.
  • So, what's the attack here? There's a race condition on the checking of the k value for the origin. First, we send the request with fbconnect URL with the instagram app, which is valid. While the OAuth request is in flight we submit a new k value to replace the postMessage origin to send it. With this, we're able to get the OAuth code for any app!
  • This was fixed by checking that the app_id is the current one. While testing the fix they noticed that if you included a parameter with app_id[0]="" that this was interpreted as the parameter but could only clear it for some reason. While looking around they found a new parameter called encrypted_query_string which could contain the same information as before. The author found an encryption oracle via a server side redirect that encrypted the information for them.
  • So, using this, we submit a postMessage with the app_id and redirect_uri with the empty string to clear it. Next, we use the information provided by the encryption oracle with the malicious redirect_uri. Now, we have bypassed the protection once again. To fix this once and for all, an allowlist of JSON parameters was made for the postMessage call.
  • All of Youssef's post require a very deep understanding of the Meta ecosystem and rely on various small primitives to achieve a goal. Parameter pollution, encryption oracle... so many little things! I think this shows the power of specialization and note taking on little quirks discovered within the application to create huge impact. Youssef was on the Critical Thinking podcast recently and has some further good insights on this.