Controlling Access to Config Files, Custom Tags, and other files - Security Series #7.3
If you have an application of any complexity, or if you use any of the available frameworks that are out there, whether it is Model-Glue, Mach-II, ColdBox, Transfer, ColdSpring, etc. then you are going to have config files, custom tags, template files or some other files that need to be protected.
Config files can contain a lot of sensitive information that you do not want others to see. DNS names, usernames, passwords, file paths, reinit strings, etc.
You may also have other files, templates, custom tags, and includes that you don't want your users to be able to access directly. Calling such files directly can cause errors due to missing variables, queries, objects, etc.
To protect these files we have several options:
Using .htaccess files or IIS directory security to protect the contents
Using Apache .htaccess files with appropriate settings you can restrict access to a directory simply by placing a file with the following code into the directory to which you wish to restrict access.deny from all
Options -Indexes
The first statement tells Apache to deny all requests to access the contents of the directory. The second statement tells Apache not to list the contents of the directory if no index.cfm (or other index file) exists.
Now, if you want, you could be more specific. Like if you had a certain file you wanted to restrict access to, but it was in a directory with other files, you could do this:
<files config.xml>
order allow,deny
deny from all
</files>
The ORDER directive in the first line tells Apache to process all ALLOW directives first, then to process all DENY directives. This is important, because if it fails to find a match in the deny/allow directives that follow, then it will automatically give the permission that is listed last. To err on the side of caution, we always want to deny if no match is found.
The second line is a simple deny directive telling Apache to deny all requests for this file.
Something similar can be done with IIS using the IIS Snap-in in the Microsoft Management Console:
- Browse to the directory or file you wish to secure
- Right click on it and choose Properties
- Go to the Directory/File Security Tab
- Uncheck "Enable Anonymous Access"
Renaming the config files to .cfm and using a <cfsetting> tag
Another options for securing the contents of a config file, like the standard XML config files you find in common frameworks is to rename the file to include a .cfm extension and add the following code to the first line of the file.<cfsetting enablecfoutputonly="true" />
This will suppress any output that is not enclosed in <cfoutput> tags. So even though the end user would be able to request the file, it would show up blank and its source code would reveal nothing.
Note: You probably don't want to do this with Custom Tags.
Including an Application.cfm file with a <cfabort> inside
In conjunction with renaming a config file to .cfm or when protecting custom tags or templates that are already .cfm files, you can use a very simple method to keep these files from being called directly.By placing an Application.cfm file in the directory with a single <cfabort> tag in it, you will ensure that if anyone tries to call a .cfm file from within that directory directly that they will meet the <cfabort> before anything from within the file is sent to the browser.
This method does not affect the ability for other cfm/cfc files to call on these files for use. Application.cfm is only executed on the file that is called directly, it is not executed on calls made by that file to others.
Using ColdFusion Mappings
As was pointed out to me by Justice in the comments, I neglected to point out one of the easiest solutions for securing access to ColdFusion files (cfm/cfc), and that is ColdFusion Mappings. You can place your files in a directory outside of the web root and then create a mapping in the ColdFusion administrator or Application.cfc that points to that directory. If the file is request using <cfinclude>, <cfmodule>, Custom Tag Syntax (<cf_TagName>), <cfinvoke>, <cfobject>, or CreateObject() then ColdFusion will look in the mapping locations for the file before it looks in the web root. So the files can be accessed by code, but not directly.To set up a ColdFusion Mapping go to your ColdFusion Administrator and:
- Click on MAPPINGS under the Server Settings Menu
- Enter a Logical Path for the mapping, this is the name of the folder where ColdFusion will look for the file. So if your file, if not in a mapping, would be located at /model then your Logical Path would be /model
- Next enter the Directory Path this can be anywhere else on the server. Windows example: c:\myFiles\cfcs\AppModel
- Click Add Mapping
Where possible, especially in a shared hosting environment or where you do not have access to the ColdFusion Admin, you should use Application Specific Mappings set up in the Application.cfc
The mapping above could be added via the Application.cfc with the following code:
<cfset THIS.mappings["/model"]="c:\myFiles\cfcs\AppModel">
This code would go in the pseudo-constructor of your Application.cfc along with the statements for this.name and this.sessionManagement, etc. NOTE: Application specific mappings are new to ColdFusion 8. You cannot use them in previous versions.
I am sure some types of mappings are also available in Railo and OBD, but I am not familiar with those servers, so I cannot describe the process.





Thanks again Justice for the reminder.
<cfsilent> is probably better than <cfsetting> as a way of ensuring nothing is sent to the browser.