I've had a bit of wine this evening, so if this post seems to ramble, you know why. Also, please permit me the novelty of thinking aloud in this blogpost. Generally, I reserve this blog as a sort of lab notes area, but this time my discussion is not a direct product of my work. Instead, I'm trying to connect some things in my head that may not have a natural connection, but I think they do.
Most web frameworks will list security among the tenets of their design. Lift will talk about precluding XSS vulnerabilities, ASP.NET will mention its MAC validation of viewstate, and, honestly, I don't have any other examples at hand. But, I think it should be self-evident that web frameworks think about security.
...their security, the security of the platform, the bumpers in the gutter of web security bowling lanes are what they tout. But, dear reader, what have they offered in the way of a framework for application security? Most of us, rightly, assume that our platform is secure against exploits out of our control. Further, we appreciate those features that force us to fall into the pit of success as concerns security or naively rail against the nominal complications imposed by those features. What I have never heard anyone talk about is application security.
In line-of-business applications, the security conversation isn't about XSS or buffer overruns or SQL Injection or phishing. For those of us that build custom LOB applications, the conversation is about:
- sales people walking away with lists of customers,
- call center employees stealing credit card information,
- preventing users from making expensive mistakes,
- protecting the identity of patients, customers, or abuse victims.
In short, the LOB application developer, be she working for a government human welfare agency or a gypsum supplier, is less concerned about external hackers and more concerned about internal security. This is as it should be, as it must be. Most LOB developers don't have the capacity to evaluate the security of a web framework as a platform, and the threats they are being paid to guard against aren't from the outside.
Where is the web framework that makes securing the individual fields that compose a record easy? Where is the framework that makes it transparent for a certain user to be able to view columns A, B, and C without being able to edit them, while being able to view and edit columns D, and providing a full audit record of all of these actions? Where is the framework that makes it easy to prevent user's from expensing dinners over $80 without management approval? Why doesn't this framework then apply the same rules at the domain model level as well as giving us full support at the UI level?
Obviously, this is a rhetorical question, because someone has most certainly dealt with this in some non-mainstream framework. The answer, I believe, lies partially in the impedance mismatch found between the tiers of a traditional web application. It also something to do with a lack of security primitives in most platforms, I believe. Let's first look at the impedance mismatch problem, and ask if there are new technologies that could help up us close this gap.
Many of us have developed some sort of custom framework for dealing with security. However, as do most attempts at creating "security" whole cloth, it invariably has serious flaws. The problem lies in the seemingly simple question: where do we put the security rules? If we put the rules in the database, we will create triggers, constraints, stored procedures, schemas, etc. in order to enforce access control. If we choose the middle-tier, we may create policies, use code access security, or security aware factory methods. If we choose the UI, we should be fired, but the reader should not be at all surprised that this is probably the most common way security is enforced in LOB applications. When the page or screen is loaded a bunch of imperative code is executed that sets visible and disable properties on controls.
There are problems with each of these approaches. And, like most problems, they can be solved by approximating a correct solution through a lot of code. The UI approach doesn't scale as the number of screens and fields on those screens increase. The middle-tier, or business object, approach pulls too much data from the persistent store and doesn't easily tell the UI how it should behave, forcing a duplication of security logic. The database approach leaves the other tiers to fend for themselves and makes it hard to incorporate business logic into security decisions.
A through-going exposition of these shortcomings is beyond the scope of this post. No, seriously, it is, but anyone who has spent any time in the trenches and has seriously thought about this issue will have nodded their head through the last paragraph, I think. I did, however, intimate that their might be something coming out for .NET that could help us with this problem. And, I believe there is such a beast: expression trees. The expression trees that made Linq to Sql (aka dlinq) possible are exactly what you need in a generalized security framework.
Dlinq expression trees are a representation of the current execution environment's intent to access data. From a data-reading perspective, they are declarative intent. Presuming this model is extended to the other CRUD operations: create, update, and delete, the various expressions trees could be pruned. Or, perhaps, the leaf nodes could be filtered. The point is that expression trees and the lambda expressions that create them are data, and security policies can be applied to data. If we used declarative code for our UI bound to declarative data access intent, shouldn't we be able to defer access evaluation to runtime using declarative security policies?
Tuples are the key. Can we formulate a way to secure tuples through the application tiers? Tune in next time when I present my thoughts on how this might be possible in ASP.NET.