*Update: This was a proof-of-concept that I did back in Sept ’17. I did not expect such a great response to this project. As mentioned by many people, the code does not work anymore because WhatsApp Web keeps changing it’s code. However, I encourage you to fork my project on GitHub to make it work for your own needs.*

Ever since I started to code when I was 12 years old, I always liked to break stuff more than make stuff. Trying to go deep into the functionality of a piece of software and trying all kinds of ways to break a feature has been kind of a hobby since then. Now that I have told you that, you must’ve guessed it already that this post is about breaking a feature in a software. But more so, it is also my attempt (or you could say a proof-of-concept) at showing you that nothing is private nowadays and if you know how to break into something, well you know how to break into it.

For this particular attempt, I am trying to break one of the privacy features given to you by WhatsApp. I use WhatsApp a lot to communicate with my family and friends almost all day long and it’s an amazing piece of software. And like many other messaging apps, WhatsApp also gives you your right to control your privacy. One such feature is to hide your “Last Seen” status from people.

WhatsApp gives you the ability to hide your “Last Seen” status from others

And it works great! I always have this set to “Nobody” because I don’t want people to know when I was last online and I’m sure millions of other people do the same. But is it that safe? Can I not break it? Hmm, this is when I started to go deeper into this.

The homepage for web.whatsapp.com

Turns out that WhatsApp also has a web interface that can be used to chat directly from your browser. That’s great! I can easily look into the source code here to find my way into the underneath layers of how it all works. And that’s what I did. I went through all the scripts that make WhatsApp Web work and I found something interesting. If you go to the JS console in your browser while you’re on the website and type Store and press enter, you’ll see a particular output. And that’s how WhatsApp Web seems to be storing and retrieving stuff on your browser. It has a ‘Store’ object. Type Store.Presence.models and voila! You can now go through some details of your contacts. One of those little details is to check if a user is online, something like __x_isOnline, and after finding this I was super elated that I might have found a workaround to the “Last Seen” privacy feature by just logging the time when a user comes online and when he/she goes offline. But after some experimentation I found out that this was not a reliable way of doing so. Why? Because the param __x_isOnline disappeared when I tried to play around with it with my custom JS code. (PS. If you understand why it does then please tell me!)

A user has the “online” label to indicate his/her presence

But I obviously did not give up so easily. I thought what if I try to target just one contact at a time and just play around with the DOM. So when a user comes online, he/she has an “online” label below his/her name in the webpage. So I did the same and went on to see for DOM changes and log the activity accordingly. It worked! I could see when a particular contact of mine on WhatsApp comes online and goes offline. So even if he/she has the “Last Seen” privacy option on, I can still track when he/she comes online and goes offline. This is scary right? And it’s a small piece of code that I wrote.

Kind of the same as your “Last Seen” eh?

I call this small hack as “UhOh” because uh oh, did I just break the “Last Seen” privacy feature of WhatsApp using its own web client?

How does it work

For all you programmer peeps out there, I use Puppeteer to do this. It’s a Chrome Headless Node API released by the Google Chrome team themselves. I simple automate the process of opening up a browser page, heading to https://web.whatsapp.com, selecting the contact I want the data about and start “watching” for DOM manipulation. All this happens automatically and you get the logs in your console. More about the technicalities can be found on my GitHub repo here.

So my attempt here is not to scare people, but to show you that the concept of “privacy” is not quite a very true one in today’s world. Things can be broken easily and you can be tracked with a few lines of code, and you might not even know about it.