Within a research project on smartphone application security, I reviewed selected smartphone apps regarding security issues. One of the apps at the top of the list was WhatsApp Messenger by WhatsApp Inc.
WhatsApp Messenger is a cross-platform mobile messenger for text messaging using the existing Internet connection based on, for example 3G/EDGE or Wi-Fi. WhatsApp is available for different platforms including the iPhone, BlackBerry, Android and Nokia Symbian60 phones. Since WhatsApp Messenger uses the same internet connection as email and web browsing, staying in touch with friends is available at no additional cost which seems to be one of the main reasons for the enormous popularity of the messenger. As App Store Charts reveals, WhatsApp Messenger is one of the Top 10 paid Apps in 16 out of 22 countries. It’s even the top paid App in five countries.
One of the most criticized features of WhatsApp Messenger is the automatic synchronization of the address book with the WhatsApp backend servers. According to WhatsApp Inc., synchronization is necessary to route chat messages between different users based on their phone numbers. Using this technique, current WhatsApp users will be automatically determined from the user’s address book and displayed under Favorites, similar to a buddy list.
Today WhatsApp Inc. released an update for WhatsApp Messenger (Version 2.6.5). The update will address critical security issues I have identified:
The most critical vulnerability allows taking over any WhatsApp user account, to read messages of other users and even to send messages on their behalf. This is possible due to a design flaw within the WhatsApp Messenger registration procedure. By exploiting this weakness, devices can be registered with any phone number. Since registration in WhatsApp Messenger only depends on a phone number, a victim’s identity can easily be taken over.
WhatsApp Inc. was initially notified on June 20th. In order to fix these vulnerabilities it was necessary to redesign the registration and verification process as well as the authorization mechanisms of WhatsApp. It seems obvious that these changes couldn’t be accomplished in a short range. Therefore we agreed on a coordinated disclosure at the beginning of September.
Related Work (Update)
While there are some previous posts on security issues related to the WhatsApp Messenger, none of them had technical reversed WhatsApp Messenger to take over other user accounts. The author of the blog entry WhatsApp security hole to extract phone numbers and messages, for example, criticized that chat messages within the WhatsApp Messenger are generally sent unencrypted and could therefore be eavesdropped within a public WiFi. He suggests “to use 3G connection instead of WiFi”.
Some other authors claim to have hijacked user accounts based on an alternative activation procedure. Extracts of an old WhatsApp FAQ entry (available via some web caches):
Another way you can complete verification of your number is by sending SMS to (Edit: a phone number of WhatsApp Inc.) from the mobile number you tried to register with for WhatsApp and type your email address ONLY inside of the SMS message. For example: email@example.com (our automated system will send you the code via email once we get your SMS).
By utilizing text messaging services on the Internet which allow spoofing a sender’s number, it was possible to bypass the verification process:
Consequently, WhatsApp Inc. disabled this alternative activation procedure a few months ago.
But now, let’s have a look at my new findings!
Bypassing PIN Verification
When WhatsApp is started for the first time (without a SIM) or when a user chooses to change his number (Settings – Chat Settings), WhatsApp Messenger asks the user to enter a phone number. A verification procedure, in which a text message is sent to the new phone number should ensure that the user actually owns that number and the device.
However, this PIN verification can be bypassed by an attacker, with the consequence that any user accounts can be taken over.
Regular Verification Procedure
First, the regular verification procedure is described.
Step 1: A user is asked to enter his phone number.
Step 2: After the phone number was confirmed by the user (Figure 1) a request is issued to the backend server to deliver a text message to that number. This should ensure that the phone number is actually owned by the person claiming it.
The following HTTP(S) request is sent to the backend server to deliver a text message:
GET /client/iphone/smsproxy.php?to=4915143[..]&auth=569&in=15143[..]&code=49&udid=b33f6a2df975532f846ca[…] HTTP/1.1 […] User-Agent: WhatsApp/2.6.4 iPhone_OS/4.3.3 Device/iPhone_4 Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive
HTTP/1.1 200 OK X-Powered-By: PHP/5.2.11 Content-type: text/html Connection: close Date: Sat, 18 Jun 2011 13:48:13 GMT Server: lighttpd/1.4.24 Content-Length: 60 ID: 1308404892 #Message Receive correctly ORDERID=18542673
- Step 3: After the text message containing the activation code is delivered, the user has to enter the received 3 digit PIN (Figure 2) and complete the verification procedure.
Bypassing the PIN Verification Procedure
When having a closer look at the HTTP(S) request above, it can be seen that the PIN was already generated and cached within the WhatsApp Messenger application before it is sent to the backend servers (through the HTTP GET parameter auth). The validation of the PIN is implemented solely within the app on the client side and can therefore be bypassed.
Possible attack scenario:
An attacker could enter a mobile phone number of any user he wants to register his own device for.
On “Step 2” he could intercept the HTTP(S) request and read out the PIN (parameter auth) which, later on, is supposed to be delivered by text message.
Note: Because the request is intercepted before reaching the backend, there is actually no text message delivered to the victim.
The HTTP(S) request issued by WhatsApp Messenger already contains the PIN code required for registering a phone number:
GET /client/iphone/smsproxy.php?to=<VictimPhoneNumber>&auth=732&[...]&code=49&udid=<AttackerUDID> HTTP/1.1 […]
In the next step an attacker imitates an accurate HTTP response from the server (“Message Receive correctly”) which makes WhatsApp Messenger believe, that the text message was effectively delivered.
An attacker enters the PIN (gained from the auth parameter within the intercepted request) and the application finishes the verification procedure for any hijacked number.
Currently, this verification procedure is only implemented within the app.
Lessons learned: Security measures implemented on the client side will not be effective and should not be relied upon. All information and runtime processing on the device can be manipulated. Smartphone apps should be treated as a frontend for accessing backend services. Like in the browser based world, all security measures should be implemented in the backend.
Taking over Accounts of other WhatsApp Users
After the PIN is verified, the mobile phone number is registered at the chat service. This is necessary to route chat messages between users based on their phone numbers.
The following request is sent to the backend chat service in order to register a user:
GET /client/iphone/xmpp_reg.php?cc=49&me=<VictimPhoneNumber>&udid=<AttackerUDID>&sms=1 HTTP/1.1 […] User-Agent: WhatsApp/2.6.4 iPhone_OS/4.3.3 Device/iPhone_4 Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive Proxy-Connection: keep-alive
As can be seen from the request above, WhatsApp Messenger uses XMPP (Extensible Messaging and Presence Protocol) as messaging protocol.
Anyway, by intercepting this request, an attacker could spoof any mobile phone number (HTTP parameter me) and link this number to his UDID (Unique Device Identifier). For future authentication purposes this phone number is used as username (Jabber-ID) and the attacker’s UDID is used as password.
Even if a phone number is already registered with the WhatsApp Messenger, this request overwrites any existing credentials (probably to facilitate device changes). This way an attacker could take over accounts of any other users.
After hijacking another user’s account, any messages that should reach that particular user, are automatically redirected to the attacker’s device. An attacker could also sent messages on the behalf of the hijacked identity.
Note: A victim doesn’t notice that his account was hijacked. Only when he manually restarts WhatsApp Messenger the next time, he is informed that he cannot be registered with the chat service because of a presumed device change (this is because of the UDID change).
There are many reasons, why the UDID shouldn’t be used as an authentication token:
The UDID can be easily spoofed with freely available tools.
Because the UDID is unique for each device, it is an attractive feature for third-party advertisers looking for a means of tracking the online activities of mobile device users. More than 55% of all apps 2 are permanently transmitting the UDID to third-party tracking services. Therefore both, the phone number as well as the UDID, are not reliable for a secure user authentication.
Even Apple advises to “never store user information based solely on the UDID”. Instead Apple recommends to “always use a combination of UDID and application-specific user ID”. This is a perfect example of why Apple will deprecate the UIDevice uniqueIdentifier property with iOS 5 and above.
Lessons learned: Instead of relying on the UDID, always consider using longer term authorization tokens. These tokens should be generated on the server and issued by the backend service after a successful authentication. Don’t forget to securely store that token on the device, i.e. encrypt the token using Apple’s Data Protection API.
According to WhatsApp Inc. only the iPhone backend web services were affected by these vulnerabilities. Nevertheless, the vulnerabilities described earlier would allow reading messages of any WhatsApp users on all supported platforms (Android, Blackberry and Symbian).