What security scripts/code do you add to your application.cfm? - coldfusion

I am working on redoing our company's code, and I want to have a clear, easy to read, and reasonably secure application.cfm.
And no, we are not using application.cfc. So let's not discuss that please.
Just want to know what scripts you would add for security.
I am using coldfusion 8 standard, sql 2008.
Here is one of the scripts I am currently using, but I want to hear from some other coldfusion programmers.
<cfset temp = cleanScopes('form,url') />
<!--- another method to clean url/form data from http://www.garyrgilbert.com/tools/coldfusion/cleanScopes.cfm.txt --->
<cffunction name="cleanScopes" access="public" returntype="void">
<cfargument name="scopesToClean" type="string" required="yes">
<cfargument name="charlist" type="string" required="no" default="">
<cfscript>
reTags ="<[^/>]*>|</.*>";
</cfscript>
<cfloop list="#scopestoClean#" index="scopeName">
<cfif not findnocase("multipart/form-data",cgi.CONTENT_TYPE)>
<cfscript>
s=Evaluate(scopeName);
for(field in s)
if (isSimpleValue(s[field])){
if(reTags neq '')
do { prev=s[field];
s[field]=REReplaceNoCase(s[field],reTags,"","ALL");
} while (prev NEQ s[field]);
structUpdate(s,field,prev);
if (charlist neq '')
s[field] = replacelist(s[field],charlist,'');
}
</cfscript>
</cfif>
</cfloop>
<cfreturn>
</cffunction>
Thank you for your time.

I would advise against attempting to catch everything in a global fashion. There will inevitably be a few things that slip through the cracks, no matter how complex and convoluted your global protection code gets.
Instead, the "correct" (for what it's worth) method is to sanitize all content being presented on a page (or in an email, etc) -- during output -- that began its life as user input.
That said, take a look at OWASP. They have excellent libraries for protecting from all kinds of attacks, including the various ones you mention (sqli, xss, crlf). A coworker of mine recently wrapped up some of those libraries into a CFC that we can use in our applications, and explained how to use it on our developers blog:
AntiSamy
If your application accepts user generated HTML, say blog comments for example, you need to make sure you sanitize your input to prevent XSS attacks. You wouldn’t want someone to be able to enter malicious code in your blog comments so you need some way to filter the input. Enter AntiSamy. AntiSamy allows you to easily filter user generated HTML according to what it terms policies. AntiSamy is a Java project, so I have packaged it into a CFC for easy use from ColdFusion.
The simplist way to use AntiSamy is to create an instance of the AntiSamy component (cfc.owasp.AntiSamy) and call the getCleanHTML() method on the input.
<cfset antisamy = CreateObject("component","cfc.owasp.antisamy") />
<cfset cleanHTML = antisamy.scan(form.someInput) />
This will run AntiSamy with the default (fairly permissive) policy file and return the clean HTML markup.
ESAPI Encoder
The next library I’ve brought over from the OWASP project is the ESAPI Encoder. Again this is a Java project which I have wrapped in a CFC for easier use. The encoder provides several methods for encoding beyond those included with ColdFusion. Some of the more useful methods include encodeForJavaScript(), encodeForHTMLAttribute(), and encodeForCSS(). Using the component is pretty straight forward, just instantiate it and call the appropriate method.
<cfset encoder = CreateObject("component","cfc.owasp.Encoder") />
<cfset html = encoder.encodeForHTML("<body onload=""alert('XSS')"">Test</body>") />
One very useful method this library provides is the canonicalize method. The documentation from the beta version of the ESAPI Encoder gives a good description of what this method does.
However, if you insist on a global solution, why reinvent the wheel? Why not try out something like FuseGuard. The price is probably less than the cost of the development-hours that would be spent cobbling together, debugging, and dealing with security problems that break through your home-grown system.

Personally, I'm not really sure this "global" approach is the best. I check all incoming data in all models that accept external data, with specific validation rules for each situation. So additional layer looks overkill.
Such scripts wont protect you from putting string into the numeric id passed into the URL -- you have to check it any way. You have to use HTMLEditFormat/XMLFormat in the views any way, and so on.
P.S. List loop for CFScript:
for (i=1; i LTE ListLen(scopestoClean); i++) {
scopeName = ListGetAt(scopestoClean,i);
//... following code
}

Related

cfInclude without cfoutput tags

Ok, I have template files which I know will require to be between <cfoutput> tags, however placing a <cfoutput> tag around a <cfinclude> won't work, and anything with a <cfmodule> won't work as that doesn't allow me to manipulate the variables scope.
So, any ideas - no matter how complex - which would allow me to include such a template file and have it act as if it's between <cfoutput> tags?
Bit of context: It's for a 'framework' I am working on and requiring every template file to start and end with a <cfoutput> tag seems a real waste, especially because the less 'coldfusiony' the template files look, the better IMO.
I was going to suggest the render() option, with the caveat it's a bloody awful bit of functionality in OpenBDML (or whatever they want to call their version of CFML), and I think should be avoided. I can't see how it doesn't cause the CFML to be recompiled every request, which is a helluva overhead. I think you're better off modifying the mark-up when it gets saved/read to wrap/unwrap it in <cfoutput> tags, that way the resultant CFML will only be recompiled when the file actually changes. Which will be really a lot less often than it's read.
Prompted by your question, I did a bit of a write up on the CFML compile process, showing why having the <cfoutput> tags in a separate file doesn't work. Apologies it took so long to write & follow-up with here.
What we do in wheels is just wrap the cfinclude with a cfsavecontent tag
<cffunction name="renderInclude">
<cfargument name="template" value="string" required="true">
<cfset var myOutput = "">
<cfsavecontent variable="myOutput"><cfoutput><cfinclude template="#arguments.template#"></cfoutput></cfsavecontent>
<cfreturn trim(myOutput)>
</cffunction>
Found an OpenBD specific way to solve this problem. Apparently I wasn't the only one who encountered this problem and OpenBD contains a useful render() which takes care of evaluating cfml content. So I ended up with
<cfset cfml = fileRead(expandPath(...))>
...
<cfoutput>#render("<cfoutput>"&cfml&"</cfoutput>")#</cfoutput>
It's not a beautiful solution, as I destroy the per page compilation the engine would otherwise do, however as the cfml is relatively simple on these pages I assume this not to be too much of an issue. At least it should be less of a performance hit than actually writing the file to disk.

ColdFusion security by checking ARGUMENTS.TargetPage in Application.onRequestStart?

I have a ColdFusion app in which I wish to restrict access to certain pages, based on some criteria. I am currently doing it like this, in Application.cfc:
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="true">
<cfargument name="TargetPage" type="string" required="true" />
<cfif not SESSION.isAdmin and REFindNoCase("/admin",ARGUMENTS.TargetPage) >
<!--- Deny non-admin access to admin pages. --->
<cfinclude template="/notauth.cfm">
<cfreturn false />
</cfif>
<cfreturn true />
</cffunction>
My main concern is: How vulnerable is the general approach of checking TargetPage against a regex, and are there ways to improve the security of this design? Specifically, I'm concerned about avoiding "canonical representation vulnerabilities." See here.
For example, using just a REFind instead of REFindNoCase would let people slide right on through if they went to "/ADMIN/". Are there are other things to watch out for here?
I know there are other designs, like using another Application.cfc in a subfolder, or doing checks right in the page code. But I like the idea of having all my security code in one place. So please only suggest those in your answer if there's no way to do the above securely, or if it's just really a bad idea for some reason. Thanks.
I'm sure there are reams of this stuff on the internets but here is my take on it :)
They way I would solve your specific example is to maintain a database list of scripts that are restricted (a blacklist) unless you are a member of a certain group (i.e. you are an admin).
You can make this as complicated as you wish but for a simple start you could compare the full script name (CGI.SCRIPT_NAME) to a query of queries representing blacklisted pages you store in the APPLICATION scope that you loaded in onApplicationStart() called qRestrictedList.
So in onRequestStart you could do the following:
<cfquery name="qThisPageRestricted" dbtype="query">
SELECT * FROM qRestrictedList
WHERE ScriptName = '#CGI.SCRIPT_NAME#'
</cfquery>
<cfif qThisPageRestricted.recordCount and not SESSION.isAdmin>
<cfinclude template="/notauth.cfm">
<cfreturn false />
</cfif>
Even better, you can expand on this at a later date by wrapping all this in a 'authentication' CFC and creating user groups and levels, i.e. move your logic out of onRequestStart() and encapsulate it.
But as a start, storing the data in the database might be a more maintainable way for you to get this done and provide a better foundation for future changes to how your authentication works.
I hope this helps.
It may worth to make regex a bit stricter:
REFindNoCase("\/admin\/([A-Za-z_]+)\.cfm", ARGUMENTS.thePage)
A better approach would be to put an application.cfc in the /admin directory that controls access (maybe based on a SESSION variable set through logging in as an admin), and have that "child" application.cfc reference the parent one if necessary.
See this question for an example on how to do this: Extending application.cfc in a subdirectory

Split A CFC file into multiple files

I have been asked to update an old project. When i went into the cfc file it had over 3000 lines of code and over 100 cffunctions. I was wondering if i could split the cfc into multiple files whose cffunctions are logically grouped without having to change the code in any other pages.
Run into a similar problem. I created the new cfcs and modified the original functions to call functions within the new cfcs.
For e.g
<cffunction name="GetStuff" access="remote" returntype="Struct">
<cfreturn createObject("component","myNewCFC").GetStuff(argumentCollection=arguments)/>
</cffunction>
Refactor, Refactor, refactor...
simplest way might be using cfinclude to inject functions (mixin's)
Question implies there's enough client code using this object that changing the calls elsewhere if the object's broken apart apart is burdensome. In this case treat the existing object as a Facade - that is an object that provides unified interface to an underlying class hierarchy.
The way to approach producing the hierarchy is identifying those functions that should go together. Whenever I come across this problem the functions usually do not share any state, rather they are like static java methods, but if there are functions that share state they are a good candidate for this grouping. Otherwise it's usually functions that share the same input parameters or tend to have the same verbiage in their name (i.e. saveMyData, loadMyData, etc...).
Given that example, copy these functions into a new CFC (e.g. MyData) - at this point you may change the function names to eliminate repetition or improve their clarity (e.g. MyData.load()). Back in the original object (i.e. BigCFC) remove these functions' implementation and instead delegate the call to the newly created CFC (you may consider making the new CFC part of the old's composition). So it would look something like this:
<cffunction name="loadMyData">
<cfargument name="id" type="numeric"/>
<cfreturn variables.myData.load(arguments.id)/>
</cffunction>
Where variables.myData would be setup as part of the CFC's initialization.
Taking this approach means your existing client code is unaffected by the change, but still breaks apart everything into logic groupings, and positions new code to use the more granular CFCs.
It's an old question and I just came across it randomly, but I thought I'd chime in here as it's something I've had to deal with on many occasions.
If the goal is simply to organise things better from a code management perspective (rather than say, to specifcially reduce the amount of methods in each CFC) then I'd advocate breaking the CFC down into multiple CFM pages and including them in the CFC. From a code management perspective, you can group several functions into a well named CFM file and it all becomes a lot easier to deal with. The calling code remains the same, as all the functions are still being instantiated in the CFC as before.
I have a bit of code I use in my init methods that automatically includes all the CFM files it finds in the same folder, and I house a single base.cfc in each folder along with the grouped functions.
e.g.
<cfscript>
// Set CFC name
Variables.sCFCName = 'appUtils';
// Set folder
Variables.sCFCFolder = GetDirectoryFromPath(GetCurrentTemplatePath());
// Get CFC files
Variables.qCFCFiles = directoryList(Variables.sCFCFolder, true, 'query');
</cfscript>
<!--- Init function --->
<cffunction name="init" access="public" returnType="any" output="false" hint="Constructor">
<cfargument name="DSN" type="string" default="" hint="Datasource" />
<!--- Set DSN --->
<cfset Variables.DSN = Arguments.DSN />
<cfreturn this />
</cffunction>
<!--- Include CFC files --->
<cfoutput query="Variables.qCFCFiles">
<cfif Variables.qCFCFiles.type EQ 'file' AND GetToken(Variables.qCFCFiles.name, 2, '.') EQ 'cfm'>
<cfinclude template="#Variables.qCFCFiles.Name#" />
</cfif>
</cfoutput>

How do I force evaluation of a cfif stored in a string?

I am trying to store coldfusion code in a database to be used for the subject of a cfmail. The code stored is as follows:
"RE: <cfif myData.general.legalName NEQ """"> {{dotlegalname}}<cfelse>{{docketLegalName}}</cfif>,
DOT## {{dot}}, Docket ##(s) {{docketString}}"
When I retrieve string from the database, I use cfsavecontent to attempt to evaluate it.
<cfsavecontent variable="subject">
<cfoutput>#myData.email.subject#</cfoutput>
</cfsavecontent>
I also tried
<cfsavecontent variable="subject">
<cfoutput>#evaluate(myData.email.subject)#</cfoutput>
</cfsavecontent>
And then I replace all the {{ }} with the appropriate values.
However, the subject of the email is stubbornly refusing to contain an evaluated cfif, and is instead showing the cfif as if it were a string.
Any ideas?
The only way to dynamically evaluate code that you are creating at runtime is via writing it out to a file, and then executing it.
The easiest way would be to write it a .cfm page in the Virtual File System (probably name the file after a UUID, so it's unique), and then it where you need to run the contents.
I wouldn't normally advocate generating code at runtime like this, but it can be the most elegant solution in some cases.
As an alternative, instead of storing the CFML code in the database, you have a set of CFML email template files that get stored in a directory on your server, and in your database you simply record which template needs to be included either via cfinclude or cfmodule.
You can't dynamically evaluate CFML stored in a database without first writing it to file and then using <cfinclude> to include it.
Further to Mark's answer here is some psuedo code:
<cfset fileName = createUUID() & ".cfm">
<cfset fileWrite( fileName, [CODE_FROM_DB]>
<cfinclude template="#fileName#">
<cfset fileDelete( fileName )>
I have used code like this before with no problems. Anything in the Virtual File System flies as it is all run in RAM. For best practice do remember to delete the files created ;)
If you absolutely have to do this, look at the evaluate() function. This, essentially, fires up a new CF thread, compiles the string passed to it, runs it, and returns the result.
If at all possible, I would try to find a way to move your logic to the actual file being run, not the string from the database. I assume you are pulling the data based on some string you've already built, so you might consider appending something to it, so you are looking up subjectDotLegal and subjectDocketLegal or something similar.
Remember, evaluate() is slow, ugly, and can be dangerous (it will run anything passed to it!). If there's a way around it, I suggest you use it.
why not just use something like mustache?
http://mustache.github.com/
https://github.com/pmcelhaney/Mustache.cfc
it has the ability to not only do some of the logic that you want in your script dynamically. i really would suggest you check out the project and maybe even improve and contribute on it.
OH and just for the chance to be on a soapbox: I've been emailing Adobe for years saying that we need the ability to dynamically parse and render CFML. Sadly my cries have only gotten ignored. maybe if more people complained that this feature needs to be added, it would get the attention it deserves.
To give an example: Assume code.txt is a text file that contains the following (just to facilitate simulating CFML stored in a db): <cfoutput>#now()#</cfoutput>
The following code would work:
<cfset q = queryNew("code") />
<cfset queryAddRow(q,1) />
<cfset querySetCell(q, "code", fileRead(expandPath('code.txt')), 1) />
<cfdump var="#q#">
<cfset newCodeFile = expandPath('dynamic.cfm') />
<cfset fileWrite(newCodeFile, q.code[1]) />
<cfinclude template="dynamic.cfm" />
In OpenBlueDragon there is the render function, which can do this.
You can mimic this function in Railo by creating a custom built-in function that saves the file into RAM then cfincludes it, using the following code:
<cffunction name="render" output="Yes" returntype="string"><!---
---><cfargument name="Code" required="Yes" type="string"><!---
---><cfset local.mapping = {'/render_ram_resource':'ram://'}><!---
---><cfapplication action="update" mappings="#local.mapping#"><!---
---><cfset local.fileName = "/render_ram_resource/_render_" &
createUUID() & ".cfm"><!---
---><cffile action="WRITE" file="#fileName#"
output="#arguments.Code#"><!---
---><cfinclude template="#fileName#"><!---
---><cffile action="DELETE" file="#fileName#"><!---
---></cffunction>
(This looks unusual because it needs to allow output, but prevent extra whitespace, hence why all the comments. Unfortunately SO's syntax highlighting seems to be confused by them.)
If you need an ACF-compatible solution, you'll need to use the regular filesystem and a pre-created mapping. (Well, in ACF9 and above you can use the RAM virtual filesystem, but afaik you can't create mappings on the fly like this.)
There's a better way, namely using in memory files. This way you don't have any I/O on the disk and therefore much faster:
For tags that take logical path, define mapping in Administrator. Execute in-memory CFM pages using the cfinclude tag:
Create a mapping for ram:/// so that it can be used in the tags. In this example, /inmemory is the mapping that points to ram:///.
For tags that take absolute path, specify the syntax as provided in the following example:
You can also delete the file from the ram usinf cffile and action delete.
Here's how I stored my header and footers for all pages in a record. This code can go at the top of each page. But I have it in the APPLICATION.cfm and it seems to be working great.
The key here is not use #pound# signs on your expressions. User [square braces]. The code will pick them and evaluate them and return the result back to the template.
It will substitute the number 0 if it can not evaluate an expression as a means of error handling.
<CFSET FooterID=1234> <!-- ID of the record you want to use -->
<CFQUERY NAME="StoredHeader" Datasource="DS1">
Select Body from templates where id=#FooterID#
</CFQUERY>
<CFSET Parse=StoredHeader.Body>
<CFLOOP CONDITION="FindNoCase('[',Parse,1) GT 0">
<CFSET STB=FindNoCase('[',Parse,1)>
<CFSET ENB=FindNoCase(']',Parse,1)>
<CFIF ENB-STB GT 0>
<CFSET BracketExp=Mid(Parse,STB+1,ENB-1-STB)>
<CFTRY>
<CFSET BracketValue=Evaluate(BracketExp)>
<CFSET Parse=ReplaceNoCase(Parse,'['&BracketExp&']',Evaluate(#BracketExp#))>
<cfcatch type="any">
<div>'Using ZERO 0 for missing <cfoutput>#BracketExp#' </cfoutput> </div>
<CFSET Parse=ReplaceNoCase(Parse,'['&BracketExp&']','0')>
</cfcatch>
</CFTRY>
</CFIF>
</CFLOOP>
<CFSET Footer=Parse>
<cfoutput>FOOTER</cfoutput>
I would try the built-in QuoteName function.

Override onMissingTemplate handling in Application.cfc

I want to handle a scenario where user hits a url of /somePage.cfm when that template doesn't exist and use a template from another directory. I know I can do this via rewrites in apache etc. but I don't really want to store logic in there so I gave trying to override onTemplateMissing behaviour in my Application.cfc.
It seems to be working fine in my testing but I'm worried by doing this hacky solution I'm short cutting some parts that I haven't seen yet (e.g. methods that I'm not currently using such as onSessionStart etc.) and may run into issues in the future.
Here is what I'm currently doing:
<cffunction name="onMissingTemplate">
<cfargument name="targetPage" />
<!--- Handle any templates that we're really loading from elsewhere --->
<cfif isFooTemplate(arguments.targetPage)>
<cfset onRequestStart(arguments.targetPage) />
<cfset onRequest(arguments.targetPage) />
<cfset onRequestEnd(arguments.targetPage) />
<cfreturn true />
</cfif>
<cfreturn false />
</cffunction>
Note that also in my onRequest method I'm doing further handling for templates that isFooTemplate() would return true to.
I don't think this is a hacky solution. This is what the method is for, and on returning false, ColdFusion will invoke the standard error handler you setup in the administrator if you want.
The only case were onSessionStart() hasn't run is if the user hits the onMissingTemplate() on the first ever page request. If you for some reason need the user to have a session, you can check for the existence of the session scope, since the session scope is supposed to be available in the onMissingTemplate() method and handle appropriately.
It's actually onMissingTemplate not onTemplateMissing; and this is a recommended practice, not 'hacky' at all. You're fine doing it this way.