I've spent the past year hacking mobile applications in an effort to uncover the most common security mistakes made during development. I found that most of the problems are related to session management – the process of authenticating the user and ensuring an attacker isn't impersonating a user or eavesdropping on the service. In most cases, a vulnerability in any single area isn't a significant liability. However, the more mistakes that are made, the easier it is to attack the app. Here is what I consider to be the seven deadly sins of mobile application session management. How many are you committing?
1. Trusting the Client
This is where it all begins. The primary sin is that developers inherently put too much blind trust into the mobile client app. The server should confirm the authenticity of every request from the application and treat every input as a possible attack payload. It is very similar to normal life, for example how often are you asked for your ID when using a credit card at a store? By failing to verify your identity the store is opening themselves and the credit card agencies to fraudulent purchases.
2. Not Requiring Encryption
Mobile devices use wireless communication, and it is easy for an attacker to peek in on that traffic. To limit what an attacker can easily see, it is necessary to encrypt the communication with SSL. In too many cases I see mobile apps failing to use SSL, or when they do use SSL, they fail to require valid certificates making it useless for securing communication.
Developers also leave users clueless about the use of encryption by their mobile apps so they have no idea if their information is being broadcast to anyone who cares to look.
3. Allowing Lifetime Sessions
Mobile application sessions often last for a very long time because mobile users hate to login again. The session for some apps might be valid for months or even years. As long as they can keep the session alive, attackers can make malicious requests, effectively impersonating users. Additionally when a phone is lost, these apps have active sessions open.
It is simply a bad idea to trade away all security in favor of a minor inconvenience to users.
4. Not Keeping Secrets
Once a mobile app authenticates with a server, it is given a session token that is used for identification from then on. This session token is sent with every request to the server, and can often be seen and stolen by attackers. To improve security, developers need to keep a secret token on the mobile client that can be used to perform extra security checks. This is like a secret encoder ring. The client can use the secret encoder ring to “sign” all of its requests. Since the secret encoder ring is not sent with each request, it cannot be easily stolen and is a great way to confirm the validity of each request.
5. Not Limiting the Amount of Time a Request is Valid
Mobile apps make requests to send data or get data. These requests need to be time stamped to limit how long they are valid. The longer a request is valid, the more time an attacker has to work with. Sometimes these requests are not sent immediately (for example, when the connection is interrupted, as when the user is going down the elevator, in a parking garage, etc.). Thus, developers allow requests some time to be received by the server. However, the business must define a limit that makes sense. This limit is defined on the server side, and the requests need to be time-stamped on the client side. Once the time limit is past, the request becomes invalid and the client has to create a fresh one if needed.
6. Allowing Repeat Requests
When attackers intercept communication from a mobile device, they have several options depending on their motivation and desired impact, but one option is to simply replay those requests as is. If the request is to send a Tweet, maybe it has little impact besides being annoying. However, if the request is to transfer money and that request gets sent over and over again, this can have real monetary impact. This can be prevented by using a NONCE (number used once) on every request.
Here's how the NONCE works:
The client generates a random number – the NONCE – for each request made. The server keeps a list of the used NONCE's, and once a number has been used before, the server knows that future requests with the same NONCE are invalid.
This should be combined with advice from sin no. 5. A time limit helps restrict the list of NONCE's that must be stored by the server.
7. Failing to Prevent Altered Requests
In the discussion of sin No. 6, repeat requests, we mentioned that once an attacker intercepts a request they have some choices. Instead of simply replaying the request, they may want to alter it; for example, change the account the money is transferred to. This can be prevented by “signing“ each request using cryptographic methods.
The developer can use a shared secret or a cryptographic key pair to ensure that requests are not modified. Simply creating a HMAC of the content being sent and including this with the request allows the server to confirm that the content was not altered.
So you can use the key to sign the data. For example, I'm going to send “this is a test.” I would “hash” it with my secret key, “#t@h15isat3st, nonce value,timestamp (hashed all together) (so there is no way to manipulate the nonce) they would see that secret key and they would know that only someone with that secret key would know that it's a match. Now, that it's easy for the server to verify that it's valid content, they can be confident that it's from the authenticated user.
It is important to apply all these techniques together for the most secure solution. If developers consider every request as a possible attack (no. 1) or a possible leak of information to the attacker (no. 2) then they will also want to limit the time they give the bad guys (no. 3). The developer can use the secret key (no. 4) to sign the content (no. 7), including the time stamp (no. 5) and the NONCE (no. 6) to ensure that none of the three data points are altered.
By using all of these solutions in combination, it is possible to provide a secure solution when building mobile apps.