Snapchat: Captcha Bypass in Snapchat's Geofilter Submission Process

2015-04-03T12:44:21
ID H1:54641
Type hackerone
Reporter zero
Modified 2015-05-04T01:15:06

Description

Hi,

Overview: Snapchat provides a form in which users can submit "Geofilters". These are filters which get applied to users snaps when they are in specific geolocations. The form (https://www.snapchat.com/geofilters/submit.html) allows for the submission of these "Geofilters" as an anonymous user.

The following information is submitted through this form: - Image (filter in PNG format) (image_data) - Name (user_name) - Email (user_email) - Description (description) - Notes (notes)

Vulnerability description: The HTTP header g-recaptcha-response is not validated on the server-side when submitting a Geofilter to the endpoint /_ah/api/geofilter/v1/submission located on geofilter-dot-feelinsonice-hrd.appspot.com. Any or no value can be provided for this header.

Since no CAPTCHA verification is needed, an attacker can then conduct a bulk email sending campaign on behalf of the email address no_reply.geofilters@snapchat.com. In addition to this, the attacker can spoof the contents of the email by customising the user_name, notes or description parameters.

Technical description: After successfully passing the CAPTCHA and submitting the Geofilter, a POST HTTP request is sent to geofilter-dot-feelinsonice-hrd.appspot.com :

``` POST /_ah/api/geofilter/v1/submission HTTP/1.1 Host: geofilter-dot-feelinsonice-hrd.appspot.com Connection: keep-alive Content-Length: 496 Snapchat-CSRF-Protection: not-a-secret Origin: https://www.snapchat.com g-recaptcha-response: I_love_cats_and_kittens_and_all_fluffy_things User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36 Content-Type: application/json; charset=UTF-8 Accept: application/json, text/javascript, /; q=0.01 DNT: 1 Referer: https://www.snapchat.com/geofilters/submit.html Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8

{"image_data":"abcdefg","image_type":"PNG","user_name":"Shubham","user_email":"admin+1@shubh.am","notes":"lol","description":"lol ","geofence_polygon":"[{\"lat\":34.08166844698418,\"long\":-118.35296630859375},{\"lat\":34.16465895459983,\"long\":-118.38180541992188},{\"lat\":34.10725639663118,\"long\":-118.30490112304688},{\"lat\":34.10498222546687,\"long\":-118.38180541992188},{\"lat\":34.165227101802884,\"long\":-118.33992004394531}]","start_millis":null,"end_millis":null,"is_event":false} ```

Note: In this request, the header g-recaptcha-response does not have a valid token value. Instead, for demonstration purposes I have changed it to I_love_cats_and_kittens_and_all_fluffy_things (I actually do love kittens, but that's not the point).

The same request can be sent with the very same token above or with no token at all, and it will still succeed. This is where the primary vulnerability lies.

By sending the above request, my email (admin+1@shubh.am) will receive an email along the lines of the following: https://i.imgur.com/EF588pW.png (also attached as email1.png).

We can spoof the contents of this email by modifying the "user_name" parameter sent in our request. Take the following POST request into consideration:

``` POST /_ah/api/geofilter/v1/submission HTTP/1.1 Host: geofilter-dot-feelinsonice-hrd.appspot.com Connection: keep-alive Content-Length: 496 Snapchat-CSRF-Protection: not-a-secret Origin: https://www.snapchat.com g-recaptcha-response: I_love_cats_and_kittens_and_all_fluffy_things User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36 Content-Type: application/json; charset=UTF-8 Accept: application/json, text/javascript, /; q=0.01 DNT: 1 Referer: https://www.snapchat.com/geofilters/submit.html Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8

{"image_data":"abcdefg","image_type":"PNG","user_name":"Shubham, in order for Snapchat to accept your Geofilter, you must activate by logging into https://account.snapchaat.com/verify_geofilter?id=12bc3a76-8df5-457c-bb9a-50f876a76215. Thank you","user_email":"admin+1@shubh.am","notes":"lol","description":"lol ","geofence_polygon":"[{\"lat\":34.08166844698418,\"long\":-118.35296630859375},{\"lat\":34.16465895459983,\"long\":-118.38180541992188},{\"lat\":34.10725639663118,\"long\":-118.30490112304688},{\"lat\":34.10498222546687,\"long\":-118.38180541992188},{\"lat\":34.165227101802884,\"long\":-118.33992004394531}]","start_millis":null,"end_millis":null,"is_event":false} ```

The email received by the victim (in this case my email) will look like this: http://i.imgur.com/Xkyw7gV.png (also attached as email2.png).

Impact: The link https://account.snapchaat.com/verify_geofilter?id=12bc3a76-8df5-457c-bb9a-50f876a76215 is automatically converted into a link (for most web email clients). In addition to this, some email clients (such as Gmail) will hide the rest of the email as it is a duplicate of a previous email (redundant). This makes the malicious email look even more convincing.

These factors combined, allow for a convincing email to be sent, on behalf of the official Snapchat Geofilter API email no_reply.geofilters@snapchat.com. The attacker could leverage this vulnerability to send out emails on behalf of Snapchat. Over 1000 POST requests were sent using 50 threads. No rate limiting or limits were experienced. All 1000 emails were sent.

Additionally, since the images are physically stored somewhere and the emails are sent per request - this vulnerability could also act as a DoS issue for Snapchat. The image_data field in the JSON object sent, is not checked for whether or not it is a valid image. Regardless of the contents, the contents are saved somewhere on Snapchat's servers. Through testing, I found that there were no obvious restrictions to how big of an image could be uploaded via this API.

Both email quota's and file storage quota's could be consumed through the abuse of this API endpoint.

Remediation suggestions: In order to address this design flaw, the following steps can be taken: 1. Ensure that the Captcha verification token is being validated on the server-side. 2. Limit the number of requests which can be sent to this endpoint (time based or number of submissions). 3. Set a limit on the size of the image which can be sent and/or saved to Snapchat's servers.

Please do not hesitate to contact if any additional details are required regarding this bug.

Thank you, Shubham