I've been debating posting this for the past few days. But, as it does not really disclose anything more than has been publicly discussed as of late (on this blog and elsewhere), and as it actually makes useful suggestions pertaining to securing ColdFusion (specifically from SQL injection attacks), here goes ...
Last week 0x000000 # The Hacker Webzine posted an entry entitled Attacking ColdFusion. The post primarily describes SQL injection attacks, and explains the danger inherent in not using <CFQUERYPARAM>, and also shows the right way to use the tag. It also notes:
The cfqueryparam is generally secure because it utilizes a prepared statement, that is always binded as a string, which in term is nearly not exploitable. But, many ColdFusion applications do not use the cfqueryparam mainly because developers do not know about this, and also because this feature came only in to being, with later versions of ColdFusion.
I strongly recommend that you read this post, if for no other reason then to reinforce the reality that this risk is publicly known and being exploited, and to remind yourself (and your managers, coworkers, clients, etc.) that you must address this potential vulnerability immediately!
The 0x000000 post was also referred to yesterday by ScanSafe STAT Blog in an entry which notes that monitoring in recent days indicates that ColdFusion is now the target of an attack that had been previously targeting SQL Server powered ASP sites.
Ray
--- Ben
I think this is a good wake up call for all CF developers to stop writing hack code and start paying attention to security. I know we got a good kick in the butt from this.
Ray
I think it's awesome... now, it's high time the CF community grows up and starts doing things right! ;)
If backwards compatibility is a problem (particularly if datatypes need to be guessed) is an issue, it might be possible to have a setting in the Admin to control how strictly the binding of variables is handed.
That's a pretty tricky one. There are assumptions that would have to be made, and a chance of making incorrect ones - there is always a risk. We've looked at it before, and I am sure we'll do so again.
--- Ben
Adobe could always add it as a setting. Then developers could turn it on. And if it did assume incorrectly and caused an error, they would have the opportunity to go put a cfqueryparam where it should have been in the first place. :-)
We are afforded an awesome flexibility with cfquery and preservesinglequotes(), but with great flexibility come great responsibility...
You definitely did the right thing posting this; the more awareness we can raise the better.
If you're worried about this type of attack or have already been effected by this or other issues then obviously, Intergral (the nice people behind FusionReactor) are available to help you :)
If you don't secure access to your CF Administrator, if you don't use CFQueryParam, if you decide to use PreserveSingleQuotes(), if you don't turn off robust error messages in production, then you are at risk.
You can get this functionality with this:
<cfqueryparam cfsqltype="cf_sql_varchar" null="#len(myArg) eq 0#" value="#myArg#" />
This should be a call to all of us to strive towards better practices when developing applications, and help keep fresh in our mind that we always need to keep a step ahead when it comes to application security.
Would selecting only "SELECT", "INSERT", "UPDATE", "DELETE" and "Stored Procedures" in the "Allowed SQL" option of your data source configuration in the CF Admin stop these attached as well?
--- Ben
Thanks.
--- Ben
In our query we use:
AND (InStr(TypeID,'''#id#'''))
Since ID is a text variable, how would you recommend we properly secure it. Or, is this a potential security threat.
I realize there may have been a better way to write this, but at the time of creation 7 years ago and less experience, that is how it was written.
In answer to your question, the InStr() function expects nothign more than a string as the second input. Therefore the usage of cfqueryparam here should be no different than any other string which is a parameter in a query.
AND (InStr(TypeID,<cfqueryparam value="#id#">))