Instagram’s One-Click Privacy Switch

Back in April I found three CSRF issues on Instagram, stemming from their Android/iOS App API (which is slightly different from their public API – it’s hosted on their main domain and doesn’t need an access token).

These issues were present in th…

Back in April I found three CSRF issues on Instagram, stemming from their Android/iOS App API (which is slightly different from their public API – it’s hosted on their main domain and doesn’t need an access token).

These issues were present in the following end-points:

  • accounts/remove_profile_pic – This is used to remove the profile picture from an account
  • accounts/set_private – This is used to mark a profile as private
  • accounts/set_public – This is used to mark a profile as public

Obviously the best one out of these is accounts/set_public. With a simple GET request we can reveal anyones profile and access their private pictures. Pretty cool.




Facebook patched the holes pretty quickly and I was awarded a decent bounty for it.

Once patched I checked to make sure that it was indeed fixed, and issuing a GET request returns a 405 Method Not Allowed response.




Round Two

I didn’t blog about the issue and completely forgot about it until recently. I decided to have another look at the Android App to see if there was any new end-points to play around with.

Pretty much all API requests within the app call a method named setSignedBody. This generates a hash of the parameters with a secret embedded in an .so file, meaning we can’t craft our own request on-the-fly and submit on the users behalf (without extracting the secret).




However, the three end-points I submitted still didn’t use setSignedBody (presumably because there are no parameters needed), and therefore no token is sent along. Because of this, we can submit a POST request and still perform the attack which was supposed to be fixed!




The use of setSignedBody without a CSRF token means that all end-points are vulnerable to a replay attack. You simply submit the request yourself, catch the request in Burp, and replay to the victim. Unfortunately, this is something I realised after the bug was fixed, so no screenshots available.

So the moral here is that you should double-double-check that an issue is fixed. If I’d been more thorough in testing the fix I would have spotted it sooner than four months, my bad.

Fix

This is now patched by requiring all requests to have a csrftoken parameter. Any request which is signed also requires a _uid parameter to prevent replay attacks (unless you extract the secret…).

The original proof-of-concept now returns a 400 error.




The response body is a JSON object showing the error message.




Instagram’s One-Click Privacy Switch was originally published by Jack at Jack on October 31, 2013.


Print Share Comment Cite Upload Translate
APA
() » Instagram’s One-Click Privacy Switch. Retrieved from https://www.truth.cx/2013/10/31/instagrams-one-click-privacy-switch/.
MLA
" » Instagram’s One-Click Privacy Switch." - , https://www.truth.cx/2013/10/31/instagrams-one-click-privacy-switch/
HARVARD
» Instagram’s One-Click Privacy Switch., viewed ,
VANCOUVER
- » Instagram’s One-Click Privacy Switch. [Internet]. [Accessed ]. Available from: https://www.truth.cx/2013/10/31/instagrams-one-click-privacy-switch/
CHICAGO
" » Instagram’s One-Click Privacy Switch." - Accessed . https://www.truth.cx/2013/10/31/instagrams-one-click-privacy-switch/
IEEE
" » Instagram’s One-Click Privacy Switch." [Online]. Available: https://www.truth.cx/2013/10/31/instagrams-one-click-privacy-switch/. [Accessed: ]
Select a language: