SecureState Blog

Read SecureState's award winning blog.

In the last blog in the Mobile App Security series we covered Insecure Data Storage and how data being stored locally on your device may be exposed. In this blog we will be discussing data that is sent over the network and the security of that communication.

 

Old Vulnerabilities, Different Venue

The types of issues that we find when doing assessments on mobile apps are often the same types of issues that we find when doing web application assessments. This is not surprising as we’re ultimately dealing with the same sort of client/server paradigm, and it’s essentially just a different client initiating the request. The mobile apps also interact directly with a web service or a website to send and receive their data just like a web browser would. In a typical workflow the requests are made to the server, users are authenticated, and an authentication token, such as an HTTP cookie, is returned to be used as the authentication token for subsequent requests. Often developers may assume that if the actual raw credentials are protected by using SSL then that sufficiently protects the user as it prevents an attacker from obtaining the user’s password. However, if the authentication token itself is leaked then there is no need to obtain the user’s credentials because the attacker can simply impersonate the user by stealing their “identity”. This vulnerability, in and of itself, is certainly not groundbreaking, but the mobile space introduces additional surface area where the developers will need to apply controls as well, and where we often see them forgotten. Let’s look at a real-world example of this occurring in a popular photo sharing app.

Instagram Insecurity

While looking at mobile apps during the course of research, SecureState reviewed the network traffic for the Instagram client for Android. Instagram is a hugely popular photo-sharing social networking service. Users of the app can snap a picture, apply a filter to it and then share it with friends on Instagram or to other connected social media sites. Users can connect their Instagram account with their Facebook, Twitter, Foursquare, Tumbler and Flickr accounts. What we found while inspecting the requests generated from the Instagram client is that while the initial authentication request occurred over an SSL connection to the instagram.com site, subsequent requests after that occurred in cleartext over HTTP.

Upon a successful authentication transaction to the Instagram site the user is returned a sessionid cookie which is then passed with all subsequent requests to identify the user. This cookie is then cached and passed along for any request to the instagram.com site from that point on. Remember, so far this traffic is all happening over an encrypted channel, so everything is still good at this point. Immediately after the successful login occurs a request is made to retrieve the user’s timeline, as seen in Figure 1.

Figure 1 – Request to Retrieve the Instagram Users Timeline

As you can see in this image the request is made over HTTP and the sessionid cookie is sent along with the request. If the user is on a shared network, such as a Wifi connection at a coffee shop, and we were actively performing a man-in-the-middle attack, we now have their sessionid cookie. Once we have that sessionid we can now use that to generate our own requests to the Instagram API while impersonating the user to retrieve information, post on their behalf, or even completely take over their account. As an example, Figure 2 shows a request being made to the API, which will modify the user’s account such that it becomes public. After this modification is made all photos from the user will become public, leading to a major privacy concern as well as potentially being quite embarrassing.

Figure 2 – Request Being Made to Make The Users Profile Public

While watching the traffic generated from the Instagram client it appeared that the only traffic which actually utilized SSL was the initial authentication request and updates to the user profile. All of the other requests to the API occurred over HTTP, which would also leak the sessionid. Ideally these requests should all be made over SSL to protect the confidentiality and integrity of the messages.

How to Secure It

Ultimately, addressing an issue such as this starts way back in the early phases of the Software Development Lifecycle (SDLC) where the data that is being sent back and forth is defined and the security requirements for protecting that data are also defined. In terms of architecting a solution this may mean that the API endpoint only serves up requests over SSL and does not even accept connections on cleartext protocols such as HTTP.

Additionally, any sensitive cookies should be marked with the ‘secure’ flag so that any browser or library which handles cookies does not disclose those over non-SSL connections. If custom code is being used to handle these cookies then they should respect the ‘secure’ flag and handle them appropriately as well.

Lastly, the server’s SSL certificate should be verified to make sure it has not been revoked, matches the hostname being connected to, and is signed by a trusted CA. The Android TrustManager does this by default; however we have seen numerous occasions where developers have overridden this class with their own version which disables some or all of the validation checks. The connection will still occur over SSL; however this can still be man-in-the-middled with no warning to the user and is just as dangerous as not using SSL at all.

Additionally, any sensitive cookies should be marked with the ‘secure’ flag so that any browser or library which handles cookies does not disclose those over non-SSL connections. If custom code is being used to handle these cookies then they should respect the ‘secure’ flag and handle them appropriately as well.

Lastly, the server’s SSL certificate should be verified to make sure it has not been revoked, matches the hostname being connected to, and is signed by a trusted CA. The Android TrustManager does this by default; however we have seen numerous occasions where developers have overridden this class with their own version which disables some or all of the validation checks. The connection will still occur over SSL; however this can still be man-in-the-middled with no warning to the user and is just as dangerous as not using SSL at all.