Hacking Tinder for Fun and Profit

August 2, 2014 | 17 Comments

match

Tinder is the new cool kid in town that everyone is talking about. I heard about the dating app from a friend of mine a few months ago. The concept behind Tinder is pretty simple. It shows you people nearby and lets you anonymously like or pass on them. If someone you like happens to like you back, Tinder makes an introduction and lets you chat with them. What makes Tinder addictive is the instant gratification people get from swiping and judging prospects.

I played around with Tinder one lazy Sunday afternoon and recalled my friend telling me how he would spend hours swiping right on Tinder just to accumulate as many matches as possible. This had me thinking, why can’t I reverse engineer Tinder and automate the swipes? After all, I’m pretty darn good at taking things apart!

Tinder like most internet connected mobile apps, uses an HTTP based API under the hood. To reverse engineer the network traffic, we need to capture it and understand it. My tool of preference for capturing HTTP traffic is Fiddler. One of Fiddler’s cooler features is its ability to decrypt secure traffic over HTTPS. It does this using a “man-in-the-middle” approach to intercept the secure packets. To the client (the mobile app) Fiddler impersonates the API web server. And, to the API web server, Fiddler impersonates the client (the mobile app).

fiddler-tinder

However, to impersonate the secure web server, Fiddler needs a SSL certificate. Fiddler dynamically generates a SSL certificate for this purpose. However, since this certificate is not signed by a Trusted Root Certification Authority, it won’t be trusted by the client (the mobile app). If the mobile app does not trust the web server, it will not talk to it. This can be easily fixed by installing Fiddler’s cert on the mobile device. Fiddler’s cert can be exported by pulling up Fiddler Options from the Tools menu.

fiddler-optons1

Now that we have installed Fiddler’s cert on the mobile device, we need to route all traffic from the mobile phone to Fiddler. There are multiple ways to do this. One easy way is to proxy the traffic to the computer running Fiddler. Fiddler’s proxy server listens on port 8888 by default.

fiddler-optons2

Let’s assume the local IP address of the computer is 192.168.1.2 (You can get your machine’s IP address by invoking ipconfig on Windows). On an Android device, proxy settings can be set along with the WiFi settings by checking “Show advanced options” as below.

android-proxy

Now that everything has been setup, it’s time to have some fun. Launch Tinder on your mobile device and watch the requests flow in real time!

fiddler

Looking at the requests, we see that Tinder assigns an authenticated user with a token which is passed back in the header of each web request. This custom HTTP header is “X-Auth-Token”. Using this token, we can execute any valid request against Tinder’s API server.

To automate Tinder likes, we care about two specific API requests. The request that returns a list of prospective matches and the request that triggers a like on a specific profile. Let’s look at these requests a little closer.

The RECS Request

The RECS POST request returns prospective matches and looks something like this.

POST https://api.gotinder.com/user/recs HTTP/1.1
app_version: 633
platform: android
User-Agent: Tinder Android Version 2.2.3
X-Auth-Token: b5b820ac-aede-4fe2-b6a3-92cc921c6a5c
os_version: 19
Content-Type: application/json; charset=utf-8
Host: api.gotinder.com
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 12

{"limit":40}

Its response is a JSON object with a collection of profiles.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 63452
Connection: keep-alive

{
  "status": 200,
  "results": [
    {
      "distance_mi": 15,
      "common_like_count": 0,
      "common_friend_count": 0,
      "common_likes": [],
      "common_friends": [],
      "_id": "5366c93490d3e94c03006b25",
      "bio": "",
      "birth_date": "1991-10-13T00:00:00.000Z",
      "gender": 1,
      "name": "Sample Profile",
      "ping_time": "2014-08-04T23:11:48.133Z",
      "photos": [
        {
          "url": "http://images.gotinder.com/0001unknown/unknown.jpg",
          "processedFiles": [
            {
              "url": "http://images.gotinder.com/0001unknown/640x640_pct_0_0_100_100_unknown.jpg",
              "height": 640,
              "width": 640
            },
            {
              "url": "http://images.gotinder.com/0001unknown/320x320_pct_0_0_100_100_unknown.jpg",
              "height": 320,
              "width": 320
            },
            {
              "url": "http://images.gotinder.com/0001unknown/172x172_pct_0_0_100_100_unknown.jpg",
              "height": 172,
              "width": 172
            },
            {
              "url": "http://images.gotinder.com/0001unknown/84x84_pct_0_0_100_100_unknown.jpg",
              "height": 84,
              "width": 84
            }
          ],
          "extension": "jpg",
          "fileName": "unknown.jpg",
          "crop": "source",
          "main": true,
          "id": "unknown"
        }
      ],
      "birth_date_info": "fuzzy birthdate active, not displaying real birth_date"
    }
  ]
}

The LIKE Request

The LIKE request is a simple GET request invoked against the ID of the user’s Tinder profile.

GET https://api.gotinder.com/like/5351dca99307257152001ced HTTP/1.1
app_version: 633
platform: android
User-Agent: Tinder Android Version 2.2.3
X-Auth-Token: b5b820ac-aede-4fe2-b6a3-92cc921c6a5c
os_version: 19
Host: api.gotinder.com
Connection: Keep-Alive
Accept-Encoding: gzip

Its response is a JSON object with a boolean value indicating whether a two way match exists between you and the liked user.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Auth-Token: b5b820ac-aede-4fe2-b6a3-92cc921c6a5c
Content-Length: 15
Connection: keep-alive

{"match":false}

Now that we know what the requests look like, let’s re-create them with some C# code. Since prospects are returned in batches, we need to invoke a single RECS request, parse out each individual Tinder ID and invoke LIKE requests against each ID.

public static List<string> GetProspects()
{
    List<string> ids = new List<string>();
    string response;

    try
    {
        using (WebClient wc = new WebClient())
        {
            wc.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
            wc.Headers[HttpRequestHeader.UserAgent] = "Tinder Android Version 3.2.0";
            wc.Headers.Add("X-Auth-Token", "b5b820ac-aede-4fe2-b6a3-92cc921c6a5c");
            wc.Headers.Add("os-version", "19");
            wc.Headers.Add("app-version", "757");
            response = wc.UploadString("https://api.gotinder.com/user/recs", "{"limit":40}");
        }
    }
    catch
    {
        return ids;
    }

    if (!string.IsNullOrWhiteSpace(response))
    {
        dynamic dataObj = JObject.Parse(response);
        if (dataObj.status == "200")
        {
            foreach (dynamic result in dataObj.results)
            {
                string str = result._id;

                ids.Add(str);
            }
        }
    }

    return ids;
}

The above method constructs a RECS request, invokes it and extracts the Tinder IDs. Json.NET is a popular JSON manipulation library for .NET and we use it above to parse the JSON response. We return a list of IDs when done.

Now that we have collected a handful of Tinder IDs, we can invoke a LIKE request against each of them.

public static void LikeUser(string userId)
{

    string uri = "https://api.gotinder.com/like/" + userId;
    using (WebClient wc = new WebClient())
    {
        wc.Headers[HttpRequestHeader.UserAgent] = "Tinder Android Version 3.2.0";
        wc.Headers.Add("X-Auth-Token", "b5b820ac-aede-4fe2-b6a3-92cc921c6a5c");
        wc.Headers.Add("os-version", "19");
        wc.Headers.Add("app-version", "757");
        wc.Headers.Add("aplatform", "android");
        try
        {
            wc.DownloadString(uri);
        }
        catch { } // Kids, don't try this in production code!

    }
}

Now that we have the code to request matches and like profiles, let’s put it all together with some nifty ol’ PLINQ for parallel execution.

GetProspects().AsParallel().ForAll(LikeUser);

Voila! Just invoke the above line as many times as you like in a loop and watch the matches pour in. That was pretty simple wasn’t it?

So, now what?

Well, that depends entirely upon you. You can use the knowledge you gained in this article for good or evil. If you are looking to meet new people on Tinder, check out CamMi Pham’s Tinder optimization hacks to make your profile look more appealing to prospective matches. If you are a software developer, you can use the techniques explained in this post of reverse engineer other apps. And lastly, if you are an evil spammer, you could write a Tinder bot to sell products to Tinder matches. The Tinderverse is your oyster 😉

Follow the discussion on Hacker News: https://news.ycombinator.com/item?id=8173197

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditPin on PinterestShare on StumbleUponDigg thisBuffer this pageFlattr the authorShare on Tumblr
17 comments
adam1117
adam1117

Once you set the proxy wifi network on your phone; are you suppose to connect to it? I'm not able to connect to the one I made.

ZoRaeShamley
ZoRaeShamley

These instructions are incomplete and very confusing...  Every step just says " do this " with no further explanation of how...

Step 2- my screen looks exactly like that already except for the thing that says MOBILE - how do I get that on there? And then...step 3 - ???  It says to find your ip address and then....it says open tinder and watch the requests pour in...but it didn't actually have me DO anything - neither fiddler nor tinder benefit from me simply looking up my IP address - so what do I DO with it? Obviously, this hasn't worked for me.


I understand that these instructions are probably written for people who are already developers...I'm only a half of a developer and they don't make sense to me.  Please help???

mashallow
mashallow

Thats why i created www.mashallow.com/tinder you can do massive likes without being a good developer

joe_markle
joe_markle

Hi, question about one of the steps: not sure how from exporting the certificate from fidder you "had" the certificate on the mobile device..?

ZoRaeShamley
ZoRaeShamley

@joe_markle I understand your confusion.  I am very confused by the incomplete instructions as well.  Try to email the file to yourself and then open the attachment on your device. it'll automatically install. That's what I did - but then I can't figure out any steps after that.

joe_markle
joe_markle

Question about one of the steps: Not sure how from exporting the certificate in Fiddler you have transferred it on the device?

ZoRaeShamley
ZoRaeShamley

@mashallow I used that and it's kind of confusing. I never saw how it worked and it would only work once and then it wouldn't let me do it again for like 5 minutes.  I can swipe right on more than 100 profiles just waiting for it to reset for me.

mashallow
mashallow

@ZoRaeShamley 

Hi, I tried to add you on Facebook so I can help you. What worked once? the "blind like 100"? What happen then exactly ? 

ZoRaeShamley
ZoRaeShamley

Well it doesn't matter now. I guess I am banned from twitter for liking too many people...

The 100 people adder thing - it didn't really "do" anything. The first time I clicked it, it at least appeared to reload, which made me think it did something, but then any time I clicked after that it didn't do anything at all for like 5 minutes. I could swipe right 100 profiles in 5 minutes.

So far the best thing I found was the tinderly tinder liker but as I said...I am banned, so while that allowed me to match 3000 people in 2 days, it also has cons. D

_Marinho
_Marinho

Hi, Yuri. Great job.
I tried to run the code and found some problems. I have analyzed the Requests using Fiddler and managed to get it working after doing some adjustments. This must be due to the latest Tinder update.


Changed the Tinder Android Version to 3.2.1, inserted my own auth token and also added the platform header and fixed the "limit" string problem (Had to put \" so the output comes out with the "). Here is what it looks like in the GetProspects method:


wc.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";

wc.Headers[HttpRequestHeader.UserAgent] = "Tinder Android Version 3.2.1";

wc.Headers.Add("X-Auth-Token", "INSERT YOUR AUTH TOKEN HERE");

wc.Headers.Add("os-version", "19");

wc.Headers.Add("app-version", "759");

wc.Headers.Add("platform", "android");

response = wc.UploadString("https://api.gotinder.com/user/recs", "{\"limit\":40}");


Also made some changes in the LIKE request:


wc.Headers[HttpRequestHeader.UserAgent] = "Tinder Android Version 3.2.1";

wc.Headers.Add("X-Auth-Token", "INSERT YOUR AUTH TOKEN HERE");

wc.Headers.Add("os-version", "19");

wc.Headers.Add("app-version", "759");

wc.Headers.Add("platform", "android");


Now it works like a charm. Thanks! =D

imnotageek
imnotageek

Why don't you make an app or something that enables users to execute your code? 


You could be making money out of this... You could call it Tinderverse, because just like you said, the Tinderverse is your oyster ;) lol

IRGeek
IRGeek

You win at the internet sir!! awesome work :)

© 2016 Yuri de Souza | Official website of Yuri de Souza – software developer and entrepreneur based in San Francisco.