Facebook's Moves - OAuth XSS

10:33 AM

Its been a while since I have blogged. I have since became a twitter person. mostly reading peoples findings.

Anyway, this is going to be a short post about causing an XSS on Moves. As many of you might know, Moves (moves-app) is a part of Facebook's Bug Bounty program.


OAuth - for those of you who dont know, is an open standard for authorization. OAuth provides client applications a 'secure delegated access' to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials.

Many big sites like Facebook, Google, Twitter and Dropbox use it to share specific access from a user to third-parties.
In http://dev.moves-app.com/ developers can create their Moves application(s) by using OAuth 2.0. meaning, by simply creating an application with redirect_uri, the thirdparty can get access to Moves profiles with the provided scope (location, access, read/write...).

The part that caused the XSS is the redirect_uri, they have blacklisted certain schemes from being added. forexample, I can't add "javascript://", "data:" and other protocols to the redirection url for the application I am creating.

If you notice carefully, those aren't the only dangerous schemes when it comes to script execution. for example, using "vbscript://" was possible. but due to the unlikely conditions that the user have to use an older version of Internet Explorer to get that executed, that was almost a dead end.

Bypassing Filter

As you might know, blacklisting may not be the right solution when it comes to XSS.

Things we know,:
it will expect either http or http(s)
schemes need to contain protocols. (://)

using dAta:// and jAvaScRipT:// worked with http(s?):// following them. because the regex wasn't checking for case sensitivity/i.

so redirect_uri=jaVaScrIpt://alert(0);//http:// is an ideal payload. because http will be treated as a comment.

However, there are no known payloads that will execute a script after using the data:// scheme like that, an ideal payload would be something like data:text/html;<script>alert(0)</script> but that wasn't possible.

Next is javascript, using javascript://alert(0) is also not an option, considering javascript will treat parts following it as a comment. turns out we can use newlines and breaks to cause script execution. so javascript://%0Aalert(0)//http:// works fine and causes that alert() we all love to see.

<a href="javascript://%0Aalert(0)//http://">Click</a>

works fine. but only in the <a>nchor context. but not in the redirection.
so Location: javascript:anything() actually doesn't work (just became aware of this because @filedescriptor mentioned it, I had no clue)

However, data:// schemes work fine. so data:// is our ideal payload. but turns out the :// isn't actually mandatory, because the http:// following in the comments can help within.

Ideal solution: daTa:text/html:base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K#http://

Errors. Errors eveywhere. Solution: URL encoding.

Simply by encoding the URL it is possible to get a working payload,

Final solution: daTa:text/html%3Bbase64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K%23

PoC: https://api.moves-app.com/oauth/v1/authorize?response_type=code&client_id=2KQ3D5coba76A5eg42mlu3L3Kd3btEeS&scope=location&redirect_uri=daTa:text/html%3Bbase64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K%23http://


UPDATE: Abdellah mentioned this can be exploited automatically using a well known OAuth misconfig. simply changing the "scope" to unknown, an error will be triggered that will force an error redirection to the redirect_uri (which in this case is the malicious paylaod). so this should work fine:
or, moves will exploit its ownself for us, with no user-interaction whatsoever. here is the secrete:

If no user-interaction is occured, moves will redirect to the redirect_uri in 9 seconds. and we simply set our malicious script as a redirect_uri and send that user to that page, even if he doesn't do anything, the exploit will trigger it self in 9 seconds. awesome!

simply by embedding the authorization url in an iframe or img tag, any moves user should be exploitable. here is a video demonstrating it:



24 November 2015 - Initial Discovery
2 December 2015 - Report
8 December 2015 - More data sent.
9 December 2015 - Escalated by Facebook
10 December 2015- Patch
10 December 2015 - Fix Confirmation

You Might Also Like


  1. This comment has been removed by a blog administrator.

  2. Another interesting articles,these information really worth saying, i think you are master of the content and get new more information after refer that post.

    digital marketing training

  3. Thanks for sharing this unique and informative content which provided me the required information.
    selenium training in chennai

  4. I would like to suggest that you stick with the ultimate Forex broker.

  5. It is amazing and wonderful to visit your site.Thanks for sharing this information,this is useful to me...
    Android Training in Chennai
    Ios Training in Chennai