It has been at least ten years ago now that I was reading an article and considering its ramifications in light of my current book. The name of the article has fallen by the wayside over the years, but the book was entitled, “.NET Development Security Solutions.” I was considering two important questions in the creation of my book:
- Is it possible to create a truly secure application?
- What is the actual cost of a secure application?
They’re essential questions and the answers to them continue to have an effect on my book writing efforts. The answer to the first question is yes—it’s possible to write a truly secure application. However, in order to obtain such an application, it can’t have any connectivity to anything. The second that an application has any connectivity, whatsoever, with anything else, it becomes contaminated by that connection. Don’t just think about users entering incorrect data here. The data on a hard drive can be corrupted, as can the memory used to hold the application. For that matter, someone could probably make the argument that it’s possible to create serious problems in the processor. My readers are a truly ingenious lot, so I’m sure if I gave you enough time, you could come up with an application that has no connectivity whatsoever with anything, but the usefulness of such an application is debatable. What good is an application with no inputs or outputs? I came to the conclusion, after quite a few hours of thought, that the most secure application in the world does nothing at all, interacts with nothing at all, and is pretty much worthless.
As I considered this security dilemma, it occurred to me that a truly secure application has no speed and is completely unreliable, given that it doesn’t do anything at all. As I worked through this book, I eventually came up with a performance triangle, where these sides are based on:
- Security: The ability of the application to prevent damage to the application data, application code, the host system, and any connected systems.
- Reliability: The accessibility of the application by the user. A reliable application is available for use at all times and makes every possible feature available to the user in a manner that precludes damage to the data or the system.
- Speed: The pace at which an application can accept input, perform tasks, and provide output.
In order to increase speed, you must remove code that provides security and reliability. (I’m assuming here that the code is already as efficient as you can make it.) Likewise, when adding security features, you decrease application availability in some situations and also add code that affects application speed. Making code reliable (which infers accessibility) reduces security and speed. The performance triangle has worked out for me for many years now as the basis for thinking about how application code actually works and the tradeoffs I must consider while writing it.
The use of the performance triangle isn’t based on language or platform. Whether you work on a Macintosh, Linux system, or Windows, you need to consider the effects of the performance triangle on your application irregardless of the host system. Likewise, language choice doesn’t affect the performance triangle, except that some languages provide more features that enhance a particular triangle element more than others. For example, C++ provides a significant speed advantage over many applications, but at a known cost to both security and reliability because the programmer is made responsible to adding the required safeguards. C# provides more safeguards, which enhances reliability, but at the cost of speed.
A problem in the current application design environment is that developers often focus on one element of the triangle (normally speed or security) at the cost of the other two. In order to build an application that performs well in a specific situation, the developer must consider the ramifications of all three triangle elements—an incredibly difficult task in some situations.
Even the questions that developers ask about the three elements of the performance triangle are often flawed. For example, many developers equate reliability with up time, but up time is only part of the reliability picture. An application that produces inconsistent results, denies required access to the user, or damages data in some way is unreliable. Robust applications explore all of the elements fully.
In the end, developers are usually faced with an imperfect scenario. Conflicting requirements and real world necessities often serve to weaken a good application design so that the developer must carefully craft the application to meet the maximum number of these requirements with the fewest possible faults. The situation comes down to one of weighing risk. A developer needs to ask which issue is most likely to cause the most harm and then write code that addresses that issue.
What sorts of design issues are you facing when developing applications? Do you use something like the performance triangle to help you consider the risks incurred when choosing one course over another in application development? Let me know your thoughts at [email protected].