So far we focused on access control, which helps to establish the "rules of the game" authentication and authorization controls who is allowed to use the app and what they are allowed to do. If you read the Android Security documentation, access control concepts dominate, but this is only part of the security story. Access control enforces the rules for customers, employees, and users who are effectively trying to get work done; however access control does little to mitigate threats of people deliberately trying to break the system.
It pays dividends to learn and apply access control services because a vulnerability here will cascade across the system and be available to attackers as well, but it pays to go further just access control in your mobile security design and development. I usually describe this situation as - I would bet a lot of money that I can beat both Garry Kasparov and Michael Jordan in a game. The way I would do this of course is to play Kasparov at basketball and Jordan at chess.
This is what attackers do, they change the rules of the game or change the game entirely. So while access control gives us the According to Hoyle security rules that the app would like to play under, the attacker makes no such assumption, the asserted rules are the beginning of the game not the end.
All security is built on assumptions, when these fails so does the access control model. For example, as we discussed in the last blog the Android access control policies are enforced in the kernel so the assumption is that the kernel hasn't been directly or indirectly subverted.
So if an app cannot be secured by access control alone, what's an Android developer to do? The requirements for access control are fairly straightforward on first pass - who is allowed to use the app and what are they allowed to do? Sure, it gets more complex from there, but the start and even endgame are fairly clear.
What's the starting point (much less endgame) in defensive coding? Threat models like STRIDE make an excellent starting point for finding requirements. Identify the key threats in the system and what countermeasures can be used to deal with them. STRIDE recommends, and I concur that data flow analysis is a practical way to begin modeling your application to discover where threat and vulnerabilities lie.
From there, refining the model with App attack surface - data, communications, and application methods, plus Mobile specific attack surface - GPS, NFC, SMS, MMS - adds more detail to both identify vulnerabilities and locate countermeasures.
The mindset of the Defensive Coder is fundamentally different than the access control mindset. The Defensive coder assumes compromise attempts and possible success at each layer in the stack. This includes standard techniques such as input validation, output encoding, audit logging, integrity checking, and hardening Service interfaces applied to local data storage, query and update interfaces, interaction with Intents and Broadcasts. Not just publishing these resources for use, but factoring in how they may be misused. How is the app resilient to attempts to crash it, an attacker impersonating a legitimate user, a malicious app with backdoors running on the device, or attempts to steal or update data?
The Threat Model cannot answer all these questions completely but it does lead the development effort in the right direction to finding ways to build margins of safety into the app.