Evik James
Evik James

Reputation: 10503

Are ColdFusion CFC's very secure when access is remote?

I am using ColdFusion 9 and jQuery.

I am new pretty new to using ColdFusion CFCs via CFAJAXPROXY. I am curious as to whether my database is at risk and how I might easily patch security holes.

I put this at the top of the page:

<cfajaxproxy cfc="brands" jsclassname="jsApp">

Here's a CFC that is used after some logs in:

<!--- ADD BRAND  --->
<cffunction name="addBrand" access="remote">
    <cfargument name="SiteID" required="true">
    <cfargument name="Brand" required="true">
    <cfscript>
        LOCAL.SiteID = ARGUMENTS.SiteID;
        LOCAL.Brand = trim(left(ARGUMENTS.Brand, 50));
    </cfscript>
    <cfquery name="GetBrands">
        INSERT INTO Brands(SiteID, Brand)
        VALUES      (<cfqueryparam cfsqltype="cf_sql_integer" value="#LOCAL.SiteID#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar" value="#LOCAL.Brand#">)
    </cfquery>
    <cfreturn true>
</cffunction>

Here's the jQuery that would post the data to the CFC

$("#AddBrand").click(function() {
    NewBrand = $("#NewBrand").attr("value");
    var jro = new jsApp();
    jro.addBrand(NewBrand);
});

So, is there a big security hole here? Should access="remote" be used only for retrieving data?

Upvotes: 5

Views: 3716

Answers (4)

Jason Dean
Jason Dean

Reputation: 9615

No, access='remote' does not need to be used only for retrieving data, but it does need to be used carefully and with an understanding of the security implications.

The way you have that set right now, anyone would be able to make a call to insert something into your DB (assuming there are no other access controls that we are not seeing). So you probably should be implementing some type of access control to protect this and other functions.

Now I am going to assume that you did not put the word "easily" in your question and I am going to put in the word "practically" instead. When it comes to security, there is rarely an "easy".

So there are several ways you could protect these methods. A lot depends on how you want to do it and what you are doing already.

  1. If you are using <cflogin> you may be able to add roles="<Your Admin role name>" to the function. I have never tried this, but I suspect it would work. (Personally, I do not like this method for several reasons, but it is an option)

  2. You can put some sort of authorization code at the top of the function.

<cfif NOT mySecurityCFC.isAuthorized(COOKIE.CFID,COOKIE.CFTOKEN)><cfreturn /></cfif>

I don't like this method either.

  1. You could use the new onCFCRequest() method of App.cfc in ColdFusion 9 to intercept requests and run them through your authorization routine. This is cleaner than option 2. I would say this is the easiest option, and would work effectively, but I, personally like option 4 better.

  2. The ColdSpring project has some great tools for automatically creating and working with remote proxy objects that can also incorporate security through Aspect-Oriented Programming (AOP). The combination of remote proxies and AOP is extremely powerful and can allow you to create the remote methods without exposing the real underlying objects and to intercept and authorize each request to those methods without having to stich code into every method. In fact, the methods themselves are not even aware they are being secured.

I would choose option 4. It may sound like a daunting and extremely high-level process, and in some ways it is, but it is actually quite a lot easier than you might think to implement. The steps are outlined in the ColdSpring quick start guide. http://www.coldspringframework.org/index.cfm/go/documentation

Upvotes: 5

jalpino
jalpino

Reputation: 150

Here is one way that you can help protect your remotely accessible CFCs from being called by 'un-authorized' applications.

Use verifyClient() or the cffunction attribute verifyClient="true"

The verifyClient() method and verifyClient attribute ensure that the calling request has included an encrypted security token which Coldfusion generated for your application. That security token is implicitly submitted along with your data when you make a call to your CFC using <cfajaxproxy>. If that token were not included in the request, Coldfusion will throw an exception.

<cffunction name="myMethod" access="remote">

    <!--- Prevent requests that have not originated from this application --->
    <cfset verifyClient() >

    ...

</cffunction>

<!-- Or --->

<cffunction name="myMethod" access="remote" verifyClient="true">

    ...

<cffunction>

** Railo 3.2.x does not support the verifyClient() method. You will have to mimic the behavior yourself if want it.

Upvotes: 3

Sam Farmer
Sam Farmer

Reputation: 4118

If you are checking that someone is logged in within your Application.cfc file then this is fine. An AJAX request is just like any other request and will go through the Application.cfc first.

You can test this out by placing an abort in onRequestStart() and seeing that nothing gets inserted. It will probably fail silently and not be the most elegant solution but it will work.

Upvotes: 3

Adam Cameron
Adam Cameron

Reputation: 29870

Well... bear in mind that if you have a method that is remotely accessible... anyone can call it. Not just your AJAX code. The CF server doesn't know whether requests are coming from your AJAX proxy or whether they're coming from anyone else just making a remote call.

And given this method does DB inserts, I think you're leaving yourself a bit open here. But this applies even with read type calls... you need to bear in mind that - by default - anyone can make the remote call and perform that read.

What you really need to do is to put some sort of authentication & authorisation in place, so only sanctioned requests can make the remote calls. Get the user to establish a session somehow (like logging in), and only accept remote requests from authorised sessions.

Upvotes: 3

Related Questions