Modifying/Deleting google drive files

This is a short write up of a bug in OAuth 2.0 implementation of Google API.

This bug could have allowed an application to delete/write on user’s any of the file(s) in google drive, although the user permitted the application to access only those files that were created by the application.

 For an instance, an application requiring access to files created by itself looks like:

According to google API documentation, after the user clicks allow, the app should only be able to access files that was opened/created using this app.

I went ahead and tried deleting a file that was in the user’s drive but wasn’t ever accessed/created by the application. Following is the request I sent to test this:

The response was 204 No content. I checked the file in my drive, the file was no longer there.
This meant any application that had drive.file permission(i.e the permission to see only those files that were created by the app itself) could have been abused to access private files of user. Not only this allowed an attacker to read all the files on your drive, but also an attacker could modify/delete those files.

This was reported to google security team and has been fixed as of now.

Jun 5, 2015 – Reported.
Jun 5, 2015 – Triaged.
Jun 11, 2015 – Additional details sent.
Jun 26, 2015 – Fix confirmation, 1337$ bounty awarded.

Update: After Google fixed this issue, I was able to bypass the fix again. The bypass involved getting ‘drive.readonly’ permission along with ‘drive.file’ permission. ‘drive.readonly’ permission made everything in the user’s Google drive visible to the application and ‘drive.file’ could still be used to delete/modify other files in user’s Google drive.

The bypass has also been fixed by Google security team.

309 Words

Stored XSS on facebook and twitter!

I and my colleague Prakash were testing random stuffs to find a target that would be worth looking into. We found a new feature on Facebook which allows a user to visit the website of page-owner.The “Shop-now” feature looked interesting with different restrictions for different input fields.
The app-link field caught my eyes, because “deep-link” URL had particularly idiosyncratic example :


The field was sanitized for special characters like < , “, ‘ , > and didn’t allow any tags to enter. The output for such characters would be:


I thought of trying ()  . Surprisingly, they weren’t being sanitized, and of course : wouldn’t be filtered for sure because it would always be used in a URL. I still wasn’t sure if any javascript would be executed. I saved the details to test it out with the applink as javascript:alert(document.domain).

But then I realized I was only couple of clicks to see if the test was successful. In, under the “shop now feature” was the script being stored. and then,

(Detailed exploit scenario is shown in video)

Script was straightforward inserted into “a href” tag and anyone clicking on the button link would be exploited.

Now, along with client side filtering, it doesn’t execute the script even if you managed to circumvent the client side protection in some way.

A very similar endpoint existed in twitter, too. You could define the action of a button click by yourself


but more on that later.

Both vulnerabilities have been patched by respective security teams.

Thanks for the read!

260 Words

How I hacked your unverified facebook accounts !

Here’s a little write-up on how I was able to delete any unverified account in facebook. By unverified, I mean those accounts who didnot yet verify their email address linked to facebook.
All (or most) of my bugs have been authentication related to many vendors, this was no different.

Here is how I did it:

The sign up function lets you create a new Facebook account but the response was different when the email was verified vs. when the email for the account was unverified. If you use a Facebook account that already has an account in Facebook (with its email unverified), the response you get is :

When clicked on the “Insert the confirmation code instead” it lets you enter 5-digit number only code.

Lets generate a dictionary from 00000 to 99999.

for i in range(0,99999):
     print '{0:05d}'.format(i)

Now, straightforward stuff! I fired up Burp, “Swiss army knife” for me.

Notice something peculiar in the last request?
Yes, the response length changes to show that you’ve made the correct guess. (AJAX response in burp response says that).

There was no rate limit on the number of requests you could make.

Some math work :
possible password = 100,000
If  number of requests = 100/sec.
Time taken to figure out the code (worst case scenario) = 15 minutes

The impact?

I could permanently delete any unverified facebook accounts within 15 minutes. You would try to recover using “password recover” feature but all your friends, PM’s would be gone. You would have to create entirely new account.

All I had to do was squander my bandwidth and keep bruteforcing (and sit back and relax).

How did I find out if an account was unverified?

Well, one way was to sign up using that email and see the response (if you are asked to enter confirmation code or not).

For a large number of emails, the other way was to enumerate facebook users first, to find out if the email had a facebook account and then use “Change email address field” to sort out which accounts have facebook associated with it and are still unverified.

A fix was deployed after 8 hours of submission.

and after 3 days, a handsome bounty followed up:

Thanks for the read!