As of this moment, OOPhoto - my latest attempt at learning object oriented programming in ColdFusion - has no security. Anyone can create galleries and post photos; anyone can also delete photos and galleries. For my next step, I'd like to add some very simple security to the application. What I am thinking is that each user will get a cookie containing a UUID (universal unique identifier) generated by the application. This UUID will be stored with the gallery record. Then, I will enforce the rule that only the authoring user (as authenticated by the submitted cookie) can delete or edit a photo gallery.
| || || || || |
| || |
| || || |
Implementation aside, where does the security handling in an object oriented application go? Now, I'm not talking about how security is checked - if the COOKIE value is checked directly or if this check is encapsulated in some sort of security service; what I'm talking about is where does the initial security check originate? And let's be very clear here on what type of security I am referring to. I'm not talking about all security calls; I'm very specifically talking about security calls that can raise exception events.
In an MVC-style application architecture, it's easy to eliminate some possibilities right away. The View cannot handle request-level security because the View is not included until the Controller has deemed it appropriate; its very rendering indicates that the user has the right to view the given View. Sure, the View can have "Access checks" for help with rendering logic (ie. the user can see this link but not this one), but it probably shouldn't throw any sort of security exceptions.
So let's move up the chain to the Controller. I have to admit, traditionally in my procedural applications, it is the Controller that initiates my security handling. But, is this really where we want to be handling security? This is actually a very tough question because not all parts of an application involve interaction with the Model. In practice, there are two fundamentally different types of security:
- Domain-Based Security
- Application-Based Security
I am coming up with this stuff off the top of my head, so I am sure the naming choices could be better; but, let me explain: By domain-based security, I am referring to security that surrounds interaction with the domain model; basically, the data of the application. For example, Sarah has the rights to edit this record but not that record or Libby has the rights to View this record but not delete it.
Application-Based security, on the other hand, is security dictated by the greater application, not by the domain. For example, Sarah needs to be logged into the administrative console before she can view the "FAQ" page. The FAQ page is static (ie. not pulling from the database) and therefore (in our example) does not interact with the domain; it does, however, still require viewing authorization based on arbitrary rules defined in the application.
So, what we're seeing here is that we have to be able to initiate a security clearance check for requests that involve domain resources (ie. interact with the Model) as well as for those requests that exclude domain resources. By this very fact, it means that the Controller must be able to initiate security checks (as opposed to just handling exceptions raised by the domain model).
But, does this mean that the Controller should handle all security checks? Or should the totality of security checks be distributed across both the Model and the Controller? My gut tells me that security should be performed in both layers of the application. But, I can't really explain that gut feeling. And you know me - if I can't explain it, I ain't doing it.
Lets take a second and think about a Controller-only security model. My first instinct against that approach is, what happens when we add another interface, like FLEX or AIR? Those have different controllers and we don't want to rely on their Controllers to implement our application security. This is true, on a thin-slice level. But, when we examine those scenarios more closely, those other interfaces are still being funneled into our main application through some sort of Remote Facade or Remote Controller. We could certainly implement security there before the call gets processed by the Model.
But, is a Remote Facade considered the Controller? Or is this now part of the Model? Hmmm. Clearly this needs more thinking. Perhaps it is time to re-read Jason Dean's security articles - see if he has any hidden gems on this topic.
For now, I think I will start to build a Controller-initiating security model. The explanation for this is that in my current application, all requests go through a local controller. As such, it makes sense to have the Controller be the first line of defense. Once that is in place, perhaps it will be easier to refactor in a way that is more sound. This is not the best plan, but I need something that I can keep moving forward with.
Looking For A New Job?
- ColdFusion & AngularJS Web Developer for rapidly growing startup - at Intuvo
- Senior Coldfusion Web Developer (UK - Kent) at EPG Health Media
- Web Developer at Bridge Catalog
- ColdFusion Developer at Company Confidential
- FT Remote Web Application Developer (ColdFusion) at Quality Matters
Nice stream of consciousness. Well thought out.
My first job out of college was for a government contractor. At 19 years old I had a security clearance and was maintaining classified systems. What company in their right mind lets a 19yo run a classified server? I had it beaten into my brain that security belongs at every level of development. The question stopped being "does security belong here?" and was transmuted into "who is allowed to use this?".
Security tokens, usually in the form of UserID and GroupID, were validated by every single function, even if there was no possible way the code could be called without having been pre-validated. Since every piece of code we wrote was ultimately turned over to someone else (the military), the assumption was that they had complete idiots working for them who would bypass any pre-validations and call every function directly. Hence, paranoia.
Since then, security clearance lapsed for years now, I've gotten significantly looser.
I remember going to DefCon something like a decade ago and listening to Bruce Schneier speak. One of the points he kept coming back to was that your security didn't have to be perfect and ironclad, it just had to make sense and be simple enough to manage. He said two things: "bad security is worse than no security", and "what's the worst thing that could happen if this thing is used by a bad person?". If the worst case scenario is annoying but not critical, then maybe you should focus on something else first.
If nothing else, his talks have made me step back from using UserID and GroupID to just using a GroupID. Even if the User is a Group unto themselves. This simplified my security functions by about an order of magnitude, and wasn't that hard for users to choke down.
But I still put security at every level. Can't help it. Don't think I'll ever get past it. (To this day I am unable to walk away from my desk without locking my workstation. It's a compulsion.)
Oh, and one more thing:
i am in ur cookies.dat, hackin' ur photoz
That sounds like a ton of responsibility to have right off the bad :) Hope that didn't take too many years off your life!
I like the idea of security favoring ease of use rather than iron-cladness. Of course, I am sure it depends on what type of application we're dealing with, but I am sure more often than not, we don't need extreme security (such as the type needed to pass a security audit).
I hope to get more of your feedback as I progress through this.
I feel like your last line requires an I Can Haz Cheeseburger Cat :) Also, just so we are all on the same page, I am not saying that storing a UUID in the cookie is a great form of security. I wanted the lowest possible entry to this topic.
Ben, I wish I did have some articles on security in an MVC or OO environment, cause that would me I was ahead of my blogging schedule :)
It has been on my list of things to work on for a while. There are so many places that security can be placed and since the application is separated into layers, no one solution can cover every layer.
Some of the things I have been thinking about are:
1. A user security object which contains all the information for the current user,including roles, individual permissions, IP address, form tokens (XSRF), etc.
2. Template mix-ins for security at the view layer, like you said for limiting pieces of the view to certain user types/roles/permissions, etc
3. Using Object factories/ColdSpring for injecting a security service into the service layer objects
4. Using a session facade for persisting and accessing the user security object
5. Using Aspect-Oriented with ColdSpring (or other framework) to add security advice to functions at the model/service layer.
This is the first time I have actually typed any of this out. So it is not, likely, well-formed and I am not yet sure how I would put all of it together, or if it is an efficient idea. For all I know, this may just be buzzword soup and completely non-sensical Perhaps it is overkill for OOPhoto, but since you brought it up :)
I started working on the security stuff today. I definitely feel quite shaky on it in the context of an OOP system. Hopefully I can show something tonight or tomorrow.
So far, in a few different approaches I've played with, I've found myself putting the App security ("can I access this page or function?") in the Controller, but the Data access ("can I view this record? can I edit this record?") down in the Model. The Controller in either case is aware of the user level / ID / group whatever, passing to the Model hooks as necessary.
for what it's worth :)
I'm not too sure if you read this:
Dos and Don'ts of Client Authentication on the Web - http://www.usenix.org/events/sec2001/fu/fu_html/
I found it to an enlightening read, albeit a bit off topic. The only reason I bring it up is so that you may reconsider the UUID only model.
I'll take a look. I'm actually not using the UUID model anyway. I am just going to create a user table that has a real ID in it. My goal here is not to create the most secure application - my goal is just to figure out in a light-weight way where the security points needs to be.
Hopefully I'll have something soon to share. Thanks.
That was a good article. Something I will definitely file away for a more in-depth review. For this application, I am not going to go overkill on the security as this is less about the security implementation and more about the security "hooks."