Access Control Intro - Security Series #7

This sub-series is inspired by a question that was submitted to Raymond Camden's ColdFusion Jedi blog.

Basically, the question was about whether or not "complex security" was possible with ColdFusion. I believe he was asking about granular access control. Ray's response was fine, but both he and the questioner both commented on the fact that there were no existing posts on this topic. So I said to myself....

They were both right in saying that most security articles are about intrusion prevention and detection and slowing down hackers, and less about the how-to aspects of things like access control. One of my goals with this security series is to fix that. I started that with my sub-series on password security and I will try to continue it now.

The question of "is it possible" was already answered by Ray. The answer, of course, is "Yes". I am more interested in addressing how it can be done.

Again, I will remind everyone that this can be done in multiple ways ranging from spaghetti code procedural statements at the top of every page (and _action.cfm pages) to doing it using an object-oriented framework's proprietary methods (plugins, filters, interceptors, etc.) to using ColdSpring's Aspect-Oriented Programming techniques to "wrap" pieces of the application with security.

The methodologies I am going to show in this series are going to be basic, procedural code written to help the n00b beginner understand the concepts. That is how I learned it, and the "concepts" can be used when working with OOP and, probably, AOP.

So right now, I only going to discuss what access control is, then we will get into demonstrating a simple method of accomplishing access control. It will not be the "be-all-end-all" of access control, in fact it won't even be close. But it will get the job done.

There is a prerequisite for this series. I am assuming that you have the basic knowledge to build a session-based login/authentication system. If not, check out my series covering that and then come back to this one

What is Access Control

Access Control methodologies are like ColdFusion Blogs. Everybody's got one. And because everybody has got one, it's hard to say what the "best way" is. It's kind of like asking which framework is best. If you ask seven people you'll get nine answers.

Access control is the process of allowing or denying access to resources on a system. By allowing those that have access and denying those who do not, you are engaging in access control.

For example, if I have an administration section of my blog, and only I should have access to it, then I need to put in access control to make that happen. The authentication process is part of the overall access control. Additionally, access control can have different levels of granularity. I can allow/deny access to an entire site or I can allow/deny access to a single link on a single page

Now, access control extends beyond simple page views. Remote function calls, method calls from outside objects, and even method calls from within an object can all be consider part of overall access control. But I don't want this to get overly complicated. So for right now, we will talk about access control the way that the average developer would need it.

Examples of Bad Access Control

With the good, comes the bad. And the bad is fun to look at, so we'll start there. Most, if not all of us, have been guilty of bad access control at some time in our programming careers. So let's look, and laugh at a few of them

Hidden URLs

Hidden URLs is one of the worst examples of Access Control to ever exist. Basically, this access control method is carried out by creating a file, and then not telling anyone about it. The idea is that if you don't tell anyone about it, and you don't link to it, then no one will ever find it. RIIIIGGGGHHHHHHHTTTTTT!!!!

Of course, what the implementers of this method of access control don't realize is that they are telling people about the file. Every time they visit it, they are telling the administrator(server logs) and they are telling other users of the machine(browser history). I believe they are also telling every machine on the Internet that was part of routing the page request.

Another problem is that the file is just plain unprotected. What if a malicious user guesses the file name? What if a malicious admin at your host sees it sitting all by itself in the "admin" folder. Even if you name it something obscure, like asdfsdfsdf8798.cfm, it is still unsecure. And of course, once someone compromises it, you have no way of knowing, and no way to stop it short of renaming the file or removing it.

URL String Parameter Security

So if I ever see a URL that looks something like this:

http://www.12robots.com/index.cfm?user=jason

The first thing I would try is this:

http://www.12robots.com/index.cfm?user=admin

In a situation like this, it is likely that the extent of the access control code is:


<cfif IsDefined("url.user") AND url.user EQ "admin">
<cfset isAdmin= true>
<cfelse>
<cfset isAdmin= false>
</cfif>

This, of course, is bad. It also carries the same vulnerabilities as "hidden URLs". Server logs, browser history, Host Admins, etc.

Hiding files

File distribution is a tricky subject. If you run a site that provides files to other users on a limited basis (whether they buy them or get them with a subscription or whatever), you may need to limit access to those files from user who are not authorized. This becomes an issue for non-web type files, like PDF, DOC, or XLS files.

The non-experience developer might simply "hide" these files along the same lines as "hiding URLs" above. Not only does this carry the same vulnerabilities as hiding URLs and URL parameter security, but it also add the issue that the link to the file can easily be redistributed by a user who obtained it (legit or otherwise) and the content can be accessed for free by any user.

Cookie Based Access Control

One that I have seen, and been a part of, more often than I care to admit is cookie-based access control. Some developers are under the impression that a cookie cannot be tampered with and/or cannot be seen by the end user. That or they just think that their users are not smart enough to do it. Either way, controlling access using the cookie is just plain bad.


<cfif loginPassed()>
<cfcookie name="isLoggedIn" value="true">
<cfcookie name="userID" value="30">
</cfif>

This code assumes that there is a function called loginPassed() that is called by the login page. If the user passes the (no doubt) rigorous authentication process, then 2 cookies are set. The first will determine if the user is logged in, the second will tell the server which user. That way the server will only grant access to user 30's assets to user 30, right?

Well, using firefox plugins like Add N edit Cookies or Edit Cookies any user can easily edit their cookies. So changing that user id from "30" to "1" would be very easy. And can any one guess who user "1" usually is?

Wrap up

So those are some example of bad access controls. In this series we will look at some better ways to handle these situations.

Comments
Jason Dean's Gravatar Just made a minor update to the code, in the "URL String Parameter Security" Section. I had cfset isLoggedIn instead of cfset isAdmin
# Posted By Jason Dean | 6/24/08 7:17 AM
Bradley Moore's Gravatar I thought application scope reinitialization would be worth pointing out while you're posting about access control in CF apps. It's something I would like to see how others handle as well.

It seems to be fairly common in my experience to look for a certain url variable ( URL.reinit , URL.reset , etc ) in onRequestStart and then do your application scope setup if the variable exists. This is similar to the hidden url admin section you described.

An attack designed to bog down your sever would be to repeatably reinitializing your application by appending ?reinit=1&reset=1&config=1 in and endless loop.
# Posted By Bradley Moore | 7/2/08 2:46 PM
Jason Dean's Gravatar @Bradley - You're right! Controlling access to your application reinitialization process is absolutely a part of Access Control. Someone targeting your site for a Denial of Service(DoS) attack would have a considerably easier time with it if they knew your reinit params. Good Call!

Excuse while I go change mine :)
# Posted By Jason Dean | 7/2/08 4:21 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1. Contact Blog Owner