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: Tale of $126k worth of bugs that lead to Facebook Account Takeovers- 614

Youssef SammoudaPosted 4 Years Ago
  • Facebook allows for online game owners to host games in apps.facebook.com within an iFrame. Since this is an iFrame, cross window communications via postMessage must be done, which is hard to do securely!
  • To find these bugs, the author thoroughly audited the the client-side code and seeing the inputs/outputs throughout. The author shows the minimized code that they remained in order to be better to review.
  • The flow of this is a little complicated. The flow works like this:
    1. iFrame sends message to the parent.
    2. Message event dispatcher in XdArbier passes the data to handleMessage function.
    3. This is passed to JSONPRC call, which pops a dialog box to show the user about the author of the app.
    4. If all checks out, PlatformDialogClient is called to make a POST request to apps.facebook.com/dialog/oauth.
    5. This endpoint returns an access token, which is sent back to the iFrame containing the access token.
  • The author mentions a few potential items of interest:
    • IFRAME_ORIGIN is used in the redirect_uri parameter of OAuth. Making this go to the wrong location could allow for a classic OAuth attack that steals the access token.
    • Keys and values within the params object. Some of these parameters are attached to the OAuth POST request mentioned above, such as the APP_ID and the IFRAME_ORIGIN.
    • What if we could convince IFRAME_ORIGIN and the APP_ID that we were a different app, such as Instagram? Of course, there is protection in place!
  • The first vulnerability is parameter pollution with a desync between from the frontend verification and backend understanding. When making the call to PARAM[random it would replace the actual parameter with this value, even though the client side did not do this! As a result, we have a desync between the understanding of the redirect_uri for the frontend and backend.
  • Using the desync mentioned above, we can set the redirect_uri to be the Instagram login page and have the app ID be Instagram's as well. Now, the OAuth endpoint will return a first party token from Instagram. Parameter pollution is crazy when it works!
  • The second vulnerability is deep into the flow of the application and hits many edge cases. When validating the origin information, there is a special case for when there is no fragment being sent in the URL. When this happens, a variable named k is used instead. What is k though? Although it is not clear what it is used for, the validation of it being set is flawed, since it trusts the APP_ID that we send with it.
  • By setting k ourselves with the flawed APP_ID check, we can again get a first party token from many apps. Although, this did not work with all applications.
  • The version property in params passed in the original cross window message did not check for directory traversal or added paths. This bug occurs when adding the API version into the URL, which is user controllable. As a result, we can trick the URL in order to make queries to GraphQL on behalf of us by making the version number some point and uses a fragment to remove other parts of it. The author chooses to add a phone number to the users account, which could be used for a complete account takeover.
  • Cross origin communication with complicated authentication schemes is extremely difficult to do. It took this researcher a while to understand the whole flow of this. Once they did, it became a bug farm with fairly niche and crazy attacks. Really good article from Youssef.