|By Charlie Arehart||
|February 5, 2002 12:00 AM EST||
Many developers know that the CF administrator can restrict your ability to use several tags that not only provide very useful capabilities, but can also be used to provide unauthorized access to server resources. What many don't know is that they can arrange to use those restricted tags on a case-by-case basis with the administrator's permission.
In this article, I introduce the Unsecured Tags Directory feature, which most developers don't know about and many administrators don't understand. This feature can be the key to unlocking tags that might otherwise render a developer's intended application design difficult or impossible. I'll also explain the ability to restrict tags, for those unfamiliar with that feature.
The Closed Door to CFFILE, CFCONTENT, etc.
Have you ever wanted to use a tag such as CFFILE, but when you tried, you received the following message:
Error Diagnostic Information
The CFFile tag is disabled.
The administrator has chosen to disable this functionality on this server unless executed from a specified directory.
The problem, as the message clearly states, is that the administrator has chosen to disable or restrict use of this tag (and likely others), which might be used in an unacceptable and security-compromising way. The reasoning behind the ability to restrict such tags, and the choice by an administrator to do so, is logical and defensible.
I'll explain in more detail. What many developers and administrators don't know is that there's a way to permit access to these otherwise restricted tags. It can be done in a controlled manner that requires the administrator's complicity. The end of the error message even offers a clue as to how, but those few who do notice it still may not understand what it's implying.
Why the Closed Door?
The problem with permitting unfettered use of the CFFILE tag is that it's quite powerful and can be used for many things, including deleting files on the server or moving them around. Since the CF Server generally has rights to almost all directories on a server, it's naturally a scary prospect for a server administrator to let all CF developers access whatever files they want.
The administrator can use the "Basic Security" panel in the Administrator to select which of a handful of listed (and potentially dangerous) tags should be restricted so that no CF developer can use them. At least that's the way it appears, but this article will demonstrate that it's not entirely true.
The screen in the Administrator used to set these restrictions is shown in Figure 1. As of CF5, the Basic Security features are accessed through the new "Security" link listed below the "Home" and "Logout" links at the top left of the screen. The "Tag Restrictions" link shows this page, which indicates the tags that can be restricted. It also offers the relatively new Unsecured Tags Directory. (In CF 4.5, this page is under the "Basic Security" link in the Administrator's left nav bar and appears pretty much the same.)
By default, all the tags are unrestricted (all checked). Anyone reading the screen or the CF Administration manual will likely think that turning these tags off is the "safest thing to do." Most hosted sites run by CF administrators with at least some knowledge of the restriction option will likely disable the tags.
Sadly, it's a bit like throwing the baby out with the bathwater. There is indeed reason to fear that some might misuse a tag, but one sore point is that it's an all or nothing proposition. Once disabled, that tag can't be used at all by any developer on the server (unless you know the trick that I'll demonstrate in this article).
It's certainly reasonable to fear that someone may misuse the CFFILE Action="Delete" or Action="Move" attributes, but what if you want to use the useAction="Upload" option to allow your users to upload a file to your server? Perhaps your application needs to enable uploads of résumés, product photos, or legal documents. With the CFFILE tag disabled, your application is dead in the water. It would be nice if we could restrict certain attributes or attribute/value pairs rather than the entire tag.
What About Advanced Security?
You may be wondering why CF can't be a little smarter about the restriction of tags and simply limit the files or directories your program is allowed to access. If you could identify an application user or the owner of the application, why not just restrict which files that user or application owner can access? It involves setting up Advanced Security where you map users to resources, so people see only what they should. Because it's a bit harder to set up and that feature came out only in release 4, the simpler "Basic Security" mechanism of restricting tags is more prevalent. That basic approach needn't be a showstopper if you want to allow limited rather than total restriction of the tags, as this article shows.
Another Potentially Challenged Application
Another good example where this "all or nothing" approach can be a problem is when a developer wants to use CF to create an application that serves a repository of files available for download. Again, it could be photos, executable programs, documents, etc. He or she may want to permit end users to access these files only if they've logged in or have perhaps paid a fee. Creating a Web interface to perform authentication or accept payment is beyond the scope of this article, but well documented in other articles and books.
The issue here is how do you make those files available to the end user? While some would say, "Give them a user ID and let them FTP into a server," others would argue for a cleaner, more integrated approach. They may want the Web application to provide the file for download upon request. For this type of application, CFCONTENT comes to the rescue with its File attribute that allows you to send a given file's contents to the browser user (and even set its MIME type with the TYPE attribute).
The problem is that, again, the CFCONTENT FILE attribute would allow you to access any file and directory that the CF Server has access to (assuming you're not working under CF's Advanced Security approach). That's a problem, so many administrators restrict the tag. Again, if you want to do any sort of file serving, as described in this example application, it appears you're out of luck.
CFCONTENT is another example of a tag that should be restricted by attribute. While the aforementioned FILE attribute is risky and the DELETEFILE attribute is even riskier, the TYPE attribute can be used without either of those for an entirely different purpose. It simply sets the MIME type for the content of a page being created using CFML. This tag/attribute pair is especially critical for developers serving Wireless Markup Language applications or creating data to be read by a client as a spreadsheet. I do wish Macromedia would allow that CFCONTENT TYPE attribute to be permitted while restricting the other two.
The Tags - and Attributes - That Can Be Restricted
We've mentioned that CFFILE and CFCONTENT are tags that can be restricted. What are the rest? Prior to ColdFusion 5, the tags that could be restricted were CFCONTENT, CFDIRECTORY, CFFILE, CFOBJECT, CFREGISTRY, CFADMINSECURITY, and CFEXECUTE.
As you can see in Figure 1, release 5 added CFFTP, CFMAIL, and the new tag CFLOG to that list. It also added the ability to restrict not only tags but specific attributes of tags, namely DBTYPE=DYNAMIC and CONNECTSTRING, which are new attributes that can be used on any of several tags related to database processing (such as CFQUERY and CFSTOREDPROC). For the sake of this article, however, the interesting new feature is that we can now restrict by attribute rather than by tag only, as discussed in the previous sections.
Perhaps a future release might allow restriction of just CFFILE's Action="Move" or Action="Delete" attributes, while permitting Action="Upload"; I've lodged that as an enhancement request for the next release of CF, code-named Neo. (Then again, permitting uploads has its own security risks, as described in Knowledge Base Article 17407, "Security Best Practice: Evaluating the Risks of Allowing Uploading and of Attached Files on Your Server.")
Going back to the new list of restricted items in CF5, you may wonder why CFMAIL is listed. Though it pains me to point this out for fear it might be abused in pre-release 5 servers, the MIMEATTACH attribute of CFMAIL has always been available to send virtually any file off the server as an attachment in an e-mail sent via CFMAIL. Shocking news though that may be, it's also scary to think that a server administrator might disable CFMAIL entirely, now that it's possible. Again, I've requested an enhancement for Neo that this tag attribute be separately restricted, so that other more reasonable uses of CFMAIL can still be permitted.
It's always a dicey proposition explaining how security works (or doesn't), even if it helps solve problems. That's the nature of security, however. There's no sense living with your head in the sand. Folks who abuse systems often learn of things before those who control them, and they tend to keep their discoveries to themselves. As I so often write in this column, forewarned is forearmed.
of the Restrictions If I'm adverse to sharing security risks, why am I offering an article called "Unlocking Restricted Use of CFFILE, CFCONTENT, and More." I'll now show how to get around these sort of "global" tag restrictions. Am I again giving away the keys to the kingdom? No. In this case I'm sharing an ability to use a feature that can generally be enabled only with the concurrence and approval of the CF Administrator.
While an administrator can restrict various tags, and perhaps should - as in the case of a server shared by multiple, unrelated users - there are times, as we've seen, when this restriction can severely hamper a developer's intention to create some application feature.
Fortunately, release 4.5 and forward of ColdFusion provides an out for us in the form of the Unrestricted Tags Directory. Here, finally, is the key feature being introduced in this article. It's likely big news to many: any templates run in that directory (whether run directly, or called as a custom tag or by way of CFINCLUDE) will indeed be able to run any tag, regardless of whether it's restricted.
The option for setting this special directory is controlled by a text box appearing at the bottom of that Basic Security "Tag Restrictions" page shown in Figure 1. Many don't even notice the option. The Unrestricted Tags Directory form field is used to specify which directory on the server holds templates that are allowed to use the otherwise restricted tags. That's pretty much it. You may want to try it out.
Some additional background may be useful when considering the value to be chosen for this setting. As you can see in the figure, the value is set to "CFIDE\Ad-ministrator," which is where the CF code supporting the ColdFusion Administrator itself is located. Certainly, the CF Admin-istrator templates (which show you the Administrator interface) need to be able to execute any of these tags, whether they're restricted for all other programmers or not.
The value for this Unsecured Tags Directory is set by default to point to the directory where the Administrator code is stored. The value "CFIDE\Administrator" is the default you'll see indicated in the CF5 Server. In 4.5, the value will by default be set to the same directory but use the full path (in my case, e:\inetpub\wwwroot\CFIDE\ Administrator. The difference between using a full path and a relative one is the only difference between the two releases. In both releases, you could change it to point to any full path.
Indeed, in both releases you could point it to something other than the Administrator directory location, but you shouldn't need to and it's probably not a good idea (unless your Administrator has been placed in some other directory intentionally, perhaps for security reasons, and you need to correctly point to that). If you change it to something other than where the Administrator code is located and you disable the CFREGISTRY tag, you'll find that you won't be able to do anything else in the Administrator anymore. To regain access to the Administrator, you'll have to modify the registry to reset this key (HKEY_LOCAL_MACHINE\SOFTWARE\Allaire\Cold-Fusion\CurrentVersion\Server\UnsecuredTagsDirectory) to point to the Admin-istrator path and restart CF before being able to get into the Administrator again.
Using the Feature
If you shouldn't change the Unsecured Tags Directory to point anywhere other than the Administrator, how can you leverage this available feature as a developer? If you're not in control of the Administrator, how will any of this knowledge help?
I indicated that any template placed in this "unsecured" directory could execute any tags, regardless of restrictions. There-fore, to get around the restriction on the tags, simply place the needed code in the "unsecured" directory (or ask your administrator to do this for you). Again, any use of that template from anywhere on the server, whether called directly or by a custom tag call (with CFMODULE, to point to that directory) or a CFINCLUDE, will allow execution of the otherwise restricted tags. That's powerful.
Given the possibilities, it's probably all the more appropriate that the Unsecured Tags Directory value be left to point to the Administrator directory, since that will likely have security placed on it so browser users can't request a directory listing to see any file names that might allow unrestricted access to a tag or tags. It might even be appropriate to restrict access to that directory from the operating system level so that people on the same network can't even see what files are in that directory.
Indeed, the availability of this Unse-cured Tag Directory option, and the fact that it's set by default to the Administrator directory, indicates that it's critical that this directory be secured at the operating system level so that no one but authorized users can put files into the directory; otherwise developers would be able to grant themselves unfettered access to the otherwise restricted tags by placing templates there that use them.
(You may wonder if you can specify multiple values for the Unsecured Tag Directory. You can't. At least, it's not documented that you can, and I tried unsuccessfully to use semicolons, commas, and spaces to indicate multiple directory paths.)
A Simple Example: Enabling CFFILE Uploads
Admittedly, some servers will be run by tightfisted monarchs who won't be interested in considering the possibilities this enables. Maybe you still don't see the point. Here's a real example.
What if you wanted to get the administrator to allow you to use CFFILE even though it's restricted for the whole server? If some custom tag could be written to allow just the CFFILE Action="Upload", and that was given to the admin for approval and then placed by the admin in that Unsecured Directory, then that specific code could be called as needed by developers.
I offer an example of such a custom tag in Listing 1. Notice that it has to do a bit more than simply run the tag for us. First, it needs to account for the fact that we don't know if the user will provide all the attributes of the CFFILE action="Upload" tag; some of them are optional. Further, for some of the attri-butes we can't just default them to being an empty string if not provided, so you'll see the use of some CFPARAM tags to set the defaults to whatever the tag documentation says is the default value for that attribute (such as "delete" for NAMECONFLICT).
A couple of attributes ("mode" and "attributes") are needed only on Unix machines, but again we need to account for the fact that a value may or may not be passed in by setting a suitable default value. The default may not make sense for your installation (though these are ignored on Windows machines anyway), so feel free to change them if needed.
Finally, one other challenge is that the CFFILE tag returns several "file"-prefixed result variables, such as "file.ClientFile". Since a custom tag's variables are local to that tag and the caller will certainly need access to those variables, you'll see that I also set all the needed result variables to the caller scope, making them available to the caller.
Sadly, I couldn't do something simple like <CFSET caller.file=file> or even CFSET it to duplicate(file). The file scope isn't considered a structure. Although the release 5 docs say we should use "cffile" as the prefix over the older "file" prefix (as in cffile.ClientFile), the cffile scope reacts the same way, so I had to simply assign each expected return value to the caller scoped variable of the same name. (I used CFSCRIPT but it could just be 21 CFSETs [see Listing 1].)
If that file were saved as cffile_ upload.cfm and placed in the Unsecured Tags Directory (such as CFIDE\ Admin-istrator), then we could call it from anywhere on the server using:
filefield="photo" destination="d:\temp" nameconflict="overwrite" >
Notice that it's using CFMODULE's Template attribute to say "run cffile_ upload.cfm in the /CFIDE/ Administrator" directory. Of course, this would need to be called in the context of a form action page where the form has passed in an INPUT TYPE="file" field called "photo", and it's saying to store the file on the server in D:\temp, etc. It's a simple replacement for a CFFILE call that would have done the same thing:
<CFFILE ACTION="UPLOAD" FILEFIELD="photo"
All that's changed is the CFFILE Action="Upload". Everything else is the same. The power of all this is that the administrator can still prevent anyone from using CFFILE's more dangerous attributes. All they've opened up is the action="Upload".
If the admin still doesn't want to make such an extensible and reusable tag, they could just hard-code the values for the "destination" or even "filefield" attributes to make it useful for a single application only.
Another idea is to limit it to writing only to the directory of the caller by changing the DESTINATION attribute of the CFFILE tag within the custom tag to be:
You'd also then want to remove the CFPARAM tag at the top of the custom tag for attributes.destination, since the attribute would no longer be used. Of course, it may seem to some that such complications would make the whole concept too much bother, but I don't think so. It's still better than not being able to use the tag at all.
Finally, there's still another approach to limiting what the user can write to. You could enable the destination attribute again, but use the CFIMPERSONATE tag and its TYPE="os" attribute so users could write only to what they're authorized for. Even without Advanced Security installed, you could specify your NT domain in the tag's SecurityContext (I found I could leave it blank since my Win2k server doesn't run under the control of an NT domain server) and then pass in a username and password as attributes on the call to the custom tag. You'd wrap the CFFILE tag within this tag, as in:
<CFIMPERSONATE username="#attributes.username#"Thanks to Raymond Camden for suggesting that last solution.
password="#attributes.password#" securitycontext="" type="OS">
The ability to call upon restricted tags (indeed to restrict them in the first place) may be something that's not well understood by many CF developers and administrators. I hope this article provides information and ideas, as well as justification to approach your administrator to propose some alternatives if you work in an environment where some needed tag is restricted.
Administrators, if you've set tags to be restricted but haven't locked down that cfide\administrator directory to keep developers from freely placing files there, you've left the barn door open. I hope, too, that you'll consider using advanced security to restrict who can access what, but that's a subject for a future article (or two).
Here's one last bonus tip, since this issue of CFDJ is about using custom tags. Did you know that CF 5 introduced a means to name more than one location for globally accessible, server-wide custom tags? (This has nothing to do with the Unsecured Tags Directory.) Previously, the default location was cfusion\customtags (i.e., wherever you installed CF under the cfusion directory, such as c:\cfusion). Now you can indicate more than one location using the "custom tag paths" link in the Administrator's "Extensions" section on the main "Server" page (the first one you normally see after logging into the Administrator). While the interface for adding multiple directories is new, you could do it in previous releases by providing a comma-separated list of directories in HKEY_LOCAL_MACHINE\SOFTWARE\ Allaire\ColdFusion\CurrentVersion\Custom Tags\CFMLTagSearchPath.
Don't forget, this isn't the only way to create alternatives to the default cfusion\customtags directory for placement of globally accessible custom tags. You've always been able to create any number of subdirectories under that directory. The normal call of a custom tag as <cf_yourtagname> will look for yourtagname.cfm first in the current directory where the caller is located, then in cfusion\customtags, then in any of its subdirectories. If you wanted to run a specific tag in a specific subdirectory of cfusion\customtags, you could also use CFMODULE and its NAME attribute. See the CF docs for more information on that tag.
Some of you may be looking for Part 2 of my "Toward Better CF Administration" article that I started last month (CFDJ, Vol. 4, issue 1). Since the focus of this issue is custom tags (and it's got plenty of content already), we've decided to push that off until next month.
- Where Are RIA Technologies Headed in 2008?
- The Next Programming Models, RIAs and Composite Applications
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Constructing an Application with Flash Forms from the Ground Up
- Building a Zip Code Proximity Search with ColdFusion
- Personal Branding Checklist
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Has the Technology Bounceback Begun?
- Adobe Flex 2: Advanced DataGrid
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- Web Services Using ColdFusion and Apache CXF
- Passing Parameters to Flex That Works