When planning the security of a system, all of us developers love to get into the nitty gritty details of what NIST standards we’re implementing or the size of our keyspace. Unfortunately, this tendency can often end up resulting in missing the forest for the trees. By the same token, product managers can often make the dangerous mistake of believing that using a high difficulty randomly salted Argon2 password hash and 4096-bit RSA your application is automatically secure. Using strong cryptography is important, but we must not lose sight of what exactly we are using the algorithm for - establishing a verified network of trust, and limiting access to those in that network of trust.
Network of Trust
If you have ever done security work and it did not involve the concept of network of trust, it wasn’t security work, […] trust me, it’s the only way you can do security
When we talk about application security, we’re usually talking about verifying the authenticity of or controlling access to some piece of information. In order to do that, we first determine who we are trusting with what and how they are related - this is our network of trust. For information like a user’s email address, the network of trust may consist of just two categories of people - the user and the staff who have direct access to database server. A service like LinkedIn or Facebook may have much more complicated network of trust for the same data based on how how users are related to each other through a social graph.
This may all sound quite obvious, but it can be remarkably easy to forget. For instance, take a cashless payment system. In a closed-loop cashless payment system, we usually trust the user to view their own balance, but we do not trust them to update it or report it. The opportunity for fraud when you give the user the ability to directly manipulate their own balance is quite apparent, so most closed loop systems choose not to provide this functionality, which makes the system as a whole relatively straightforward to secure.
On the other hand, imagine you want to allow your users to make payments with their phones. This business requirement alone is quite achievable, but if you introduce the complication of needing these payments to be able to be made when neither the phone nor the payment terminal has network connectivity, you’re suddenly you’re treading in very dangerous waters when it comes to system security. Without access to a trusted central authority, the terminal generally has to put the user into their network of trust for balance information, which then leaves the system wide open for fraudulant payments.
Of course, you could also decide to accept some chance of fraud and just take measures to limit its impact. For instance, you could provide the user’s phone with a limited number of payment tokens signed by a trusted authority to provide to the terminal. This approach is wide-open to a replay attack; however, if you can ensure that terminals will rarely lack connectivity and limit the tokens to only be usable for low-value transactions for short periods of time, perhaps the amount of fraud you experience will be low enough that it’s worth the risk. Hypothetically, you could also attach a trusted hardware secure element to the user’s phone and trust that instead, bypassing many of these issues, but for most deployments, that is not a viable option.
In any case, it is critically important to first understand the networks of trust in your system before making any decisions that might have security implications. You may even discover that your desired feature set is impossible or extremely impractical to secure, which is a lot better to find out at the start instead of after development is already underway or worse - once the system has been deployed.
After you define your networks of trust, you can then start looking into exactly how you want to authenticate the various actors in the system and how you intend to control their access to information. At this point, it does start to become more about the properties of the underlying algorithms and standards, but choices there should always be informed by an understanding of the application’s network of trust.