Food for thought - method to block non-Ajax requests
A user sent in an interesting idea to me earlier in the week and I wanted to share it with my readers. It involves noticing and blocking Ajax-based requests. This kinda dovetails nicely with one of my recent InsideRIA posts (jQuery/Server Side Tip on Detecting Ajax Calls, and forgive me for not posting recent InsideRIA links - should I keep doing that?). Rob sent me the following:
I am getting into some AJAX-driven work using jQuery, and while it's all happening from secure areas of the site, I don't want people to try and backdoor into some query results by directly calling the CFC. I have 2 functions that are simple query select statements, but are accessed both publicly and remotely. What I came up with was to manage the CFRETURN calls so that if I detect the existence of url.method, to check the cgi.http_referer value to make sure it's from the pages that would be making the AJAX calls. If it is, I pass back the query. If it's not, I do a CFABORT (perhaps I'll log it in the future for what good that would do?). If I don't see url.method I assume it's not being remotely accessed so I just pass back the query.
All my queries are CFQUERYPARAM'ed so I'm not worried about injection attacks. But I was wondering if you think this is a strong enough gate to put up for this or if you have something more betterer. :)
So right off the bat, the first thing I mentioned was that the Method argument can be passed in via a form post as well, so he really needed to check url.method and form.method. I also mentioned that remote methods can be called via SOAP (web services). There's actually a CFML function for that: isSOAPRequest().
The next thing I'd probably worry about is checking the referer. I've never actually looked at the referrer values in Ajax calls. I whipped up a quick test and the CFM I called via Ajax did report a referrer value of the page itself. I'd still not trust it 100%, but it could stop some people.
At the end of the day though I'm not sure it's worth it. Rob followed up with another idea I thought might make more sense:
I did just have a thought. I use onRequest to manage access to the admin sections and that is where the ajax calls come from. I have the code in onRequestStart that looks for .cfc extensions to allow the request to work so why not also add in there a check for a valid session?
I think this makes the most sense really. Well, technically, just ensuring the session variables exist. I'm not so sure it even makes sense anymore to bother checking for ajax versus non ajax calls. If a person is authenticated and authorized to run X, do we really need to care if they run it directly versus Ajax?
Again - open question here folks. Be sure to also read the comments over on the other post as well.

I load a new token with each page, and store it in a tag somewhere on the page usually as a class name, and then pass it along with any AJAX request using the id - $("#tokenContainer").attr("class")
On Ajax calls that really need to be locked down I also check for the XmlHttpRequest header. It keeps an unscrupulous person from just opening another browser tab and trying to modify data by calling the CFC directly.
As for tokens or nonces, it seems to me that the sessionid should fill the requirements for either. If it is good enough for a regular HTTP request to verify the client, then why would an Ajax request require anything more? You can tamper with a regular HTTP request just like you could an Ajax request.
It seems to me that there is nothing that can be done from an Ajax request that can't be done via a standard HTTP request (which an Ajax request is), so why would anything extra need to be done to secure it.
I still like the idea of sensing if it is an Ajax request or not, because that might affect the format of my return data.
http://www.bennadel.com/blog/1567-Handling-Remote-...
Anyway, thanks for the inspiration!
Is this a case where you could have used the verifyClient() attribute of the cffunction tag?
http://www.cfquickdocs.com/cf8/?getDoc=VerifyClien...
Cheers
Marty
Is it possible to use it with jQuery?
http://garysgambit.blogspot.com/2009/04/ajaxbounce...
Either way, that threw a nice monkey wrench in what was otherwise a fairly decent setup I had going. Grumble.