In the third, and last, installment in the Mobile App Security Series, we will be taking a look at some common flaws found in the way that mobile apps, or more accurately, the backend services which support them, perform authentication. If you haven’t read the previous blogs here and here I suggest checking them out as well.
Complete Lack of Authentication
SecureState performed an assessment for a major retail chain on the web services which were going to be the backend API with which their mobile application would interface. The mobile application allowed customers to perform actions such as retrieving customer PII, loyalty reward points, as well as updating personal information. Upon inspection of the WSDL file which defined the structure of the web service requests, SecureState noticed that the only piece of information required to be sent to the web services was the customer’s loyalty reward number. This looked to be bad unless the reward number ended up being something other than just the reward number itself, such as an encrypted blob or random authentication token. Unfortunately, our initial assumption was correct and this truly was just the customer rewards number which, while the number is 16 digits, is just a sequential number which can be modified to then impersonate somebody else’s loyalty rewards number. To validate that there was no authentication being enforced on the web services, SecureState generated a number of requests to one of the web service methods which returned customer information and incremented our original rewards number on each request. In a short amount of time we were able to extract other customers’ full name, full address, phone number, email address, birthday and their employee ID if the account was marked as an employee. The partial results of this can be seen below in Figure 1.
Another issue that comes up when reviewing mobile apps is developers attempting to use some device specific attribute as the source of authentication for the request. While this, in theory, may be unique to the device (depending on what is used) it is not unique to the user of the device. For example, theTelephonyManager.DeviceId or android.os.Build.SERIAL attributes are essentially static and will persist across a factory reset/wipe. If one of these was to be used to authenticate and the user of the device sells or loses that phone, anybody who uses the app after that point could gain access to the previous user’s account. This certainly is not ideal nor an elegant solution for ensuring that the account owner is the only one with access to their data. Not to mention that starting with Android Jelly Bean, having multiple users on a device is a reality. Therefore, apps need to appropriately tie usage to the specific user rather than the device which is interacting with the remote server.
While possibly stating the obvious, sensitive transactions should definitely require authentication. This way you can properly make sure that the requester is actually authorized to perform the requested transaction. Generally, requiring the user to first identify themselves by entering their username and password or a randomly generated token code for them should be done.
One good solution for securing credentials in this case is to use a user’s username and password for the initial authentication request and then send a time-limited token to be used for subsequent requests which require authentication. The advantage of this method is that the user’s credentials will not need to be stored on the device and the token will have a finite period for which it is actually valid should it somehow become known to somebody besides the user. Depending on the sensitivity of the transactions involved, the app could require the user to reauthenticate with their username/password after a timeout period or the previous token could be used to retrieve a new token. The balance between security and annoying your customer base can be a fine line, so it’s worth spending the time on getting this right by having an in-depth risk analysis involving the business and security. When SecureState performs an Application Architecture Review for clients, this is an area that we dive into so that the app can be designed correctly from the start.
Including something unique about the device as part of the authentication process can also be used to make it a little more difficult to take a token from one device and use it on another; however this should be looked at as a deterrent and not a prevention mechanism. A determined attacker can always just make the requests manually through a proxy tool, a script or by modifying the values on their own device to mimic the victim’s device.
Keeping Secrets Secret
On a final note, remember that authentication is just the first step in the process. Authentication gets you the identity of who is making the request, but don’t forget to also perform the authorization checks to verify that the requester actually has the rights to perform the transaction. When you’re ready for having a third party assess the security of your mobile application, contact SecureState for a Mobile Application Security and/or Web Services Assessment.