Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with:

Accessing ColdFusion Application Settings

Posted by Ben Nadel
Tags: ColdFusion

I was just reading on Terrence Ryan's blog about introspecting the Application.cfc data. The method he uses is so simple, so obvious that it blows my mind that I haven't seen this before. I don't want to jump on his coat tails, but when I saw this, I was so excited that I felt I had to share it. So, what is the goal here? Usually the question of application introspection comes up when someone whats to do something like:

  • Check to see what the application name is.
  • Check to see if session management is enabled.
  • Check to see what the session timeout is.

The information sought out by these questions is defined in our Application.cfc ColdFusion component:

Application.cfc

  • <cfcomponent
  • output="false"
  • hint="I define the application settings and event handlers.">
  •  
  • <!--- Define the application settings. --->
  • <cfset this.name = hash( getCurrentTemplatePath() ) />
  • <cfset this.applicationTimeout = createTimeSpan( 0, 0, 20, 0 ) />
  • <cfset this.sessionManagement = true />
  • <cfset this.sessionTimeout = createTimeSpan( 0, 0, 5, 0 ) />
  •  
  •  
  • <cffunction
  • name="onRequest"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="I execute the requested template.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="template"
  • type="string"
  • required="true"
  • hint="I am the user-requested template." />
  •  
  • <!--- Include the requested template. --->
  • <cfinclude template="#arguments.template#" />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  • </cfcomponent>

It's easy enough to see in the code, but when questions like this come up, how do we access this information programmatically? To start experimenting, we will often try to do something like access the Application scope:

  • <!--- Duump out the application scope. --->
  • <cfdump
  • var="#application#"
  • label="Application Scope"
  • />

But, checking the Application scope is not very fruitful. When we run the above code, we get the following CFDump output:

 
 
 
 
 
 
Introspecting Your ColdFusion Application Settings - The Application Scope. 
 
 
 

As you can see, we only get the application name.

Next, we might look at the Application.cfc and realize that the OnRequest() event handler turns the user-requested template into a large mixin (see Application.cfc above). What this does is essentially execute the requested template in the context of the Application.cfc object, giving it access to all the Application.cfc scopes. In situations like this, you can access the THIS scope directly:

  • <!---
  • Because we are using the OnRequest() event handler, our
  • target template becomes a mixin - essentially becoming PART
  • OF the Application.cfc execution. As such, it lives in the
  • context of the application instance and has access to
  • Application.cfc scopes.
  • --->
  • <cfdump
  • var="#this#"
  • label="Template As Mixin"
  • />

When we run this code, we get the entire Application.cfc object:

 
 
 
 
 
 
Introspecting Your ColdFusion Application Settings - The OnRequest() Mixin. 
 
 
 

This gives us all the information we need, but it only works in situations where the template we are executing is included directly into the OnRequest() event method. This excludes any custom tag execution or ColdFusion component calls (not to mention AMF style execution).

At this point, we might get kinky and examine the underlying Java objects available to us. After a lot of introspection of various scopes, we might find out that the Application scope itself has some very useful, undocumented methods like GetApplicationSettings():

  • <!---
  • Dump out application settings. This is a hacky way that
  • leverages undocumented features of the language.
  • --->
  • <cfdump
  • var="#application.getApplicationSettings()#"
  • label="Undocumented Application Settings"
  • />

As you can see, here, we are accessing GetApplicationSettings(), an undocumented method on the Application scope. When we run this, we get the following CFDump output:

 
 
 
 
 
 
Introspecting Your ColdFusion Application Settings - Hiddne Java Methods On The Application Scope. 
 
 
 

This gives us exactly the information that we need; but, in order to get at it, we need to use undocumented features of the ColdFusion language. This leaves a bad taste in our mouth and opens our applications up to future bugs. Furthermore, it gives us timeout values in Seconds, not franctions of a day (as defined by CreateTimeSpan()).

So far, we've explored three different attempts at introspecting our ColdFusion application information and none of them has been fully satisfactory. That is why I was so excited when I saw Terry's blog post. His idea can be used anywhere in the application with any type of request and does not use any voodoo magic. So, what did Terry suggest? Creating a new instance of the Application.cfc ColdFusion component:

  • <!--- Create a new instance of the application object. --->
  • <cfset applicationInstance = createObject(
  • "component",
  • "Application"
  • ) />
  •  
  • <!--- Dump out the application instance. --->
  • <cfdump
  • var="#applicationInstance#"
  • label="Application Instance"
  • />

As you can see, from within the current page request, we are creating a new instance of the Application.cfc. And, when we create this instance and dump it out, we get the following output:

 
 
 
 
 
 
Introspecting Your ColdFusion Application Settings - The Application Instance. 
 
 
 

Here, we get all the information that is defined in the Application.cfc. At first, you might be nervous that we'll accidentally invoke some of the event handlers; but, that won't happen. Remember, there is nothing special about the Application.cfc ColdFusion component other than the fact that the ColdFusion server looks for it when first executing a page request. Once you are in the middle of a page execution, however, attempts to create an Application.cfc instance will be treated the same as any other ordinary CFC invocation. Essentially, all that runs is the Application.cfc pseudo constructor. As such, you won't incur any boot-up costs associated with the OnApplicationStart() event method.

A huge thanks to Terry for pointing out such a simple but awesome tip!

Tweet This Great article by @BenNadel - Accessing ColdFusion Application Settings Thanks my man — you rock the party that rocks the body!



Reader Comments

How about a nifty way of resetting the application scope for any application on your server?

Anywhere on your server, create Application.cfc and index.cfm in the same directory.

Application.cfc should have the following two lines:

<cfcomponent >

<cfset this.name= url.applicationName />
<cfset this.applicationTimeout = CreateTimespan(0,0,0,0) />

</cfcomponent>

You can then call it like this

my.server/path/to/files/?applicationName=anyApplicationName

where anyApplicationName is the value of this.name for the application's application scope you want to clear

Reply to this Comment

@Dutch,

That's an interesting idea. I am not sure that this would work on a high-traffic site since applications don't time out immediately at their cut-off points (at least in my experience). Cool idea though.

Reply to this Comment

@Ben,

Thanks for the heads up on high traffic sites. I haven't used it on production yet, mostly for refreshing things like bean factories (Lightwire, ColdSpring) on our qa/stage servers.

Reply to this Comment

To turn the post on it's head...

How would you prevent someone from dumping the application vars using CF7?

Let's say I want to encrypt my application.cfc file and leave all the other CFM templates unencrypted. Within my encrypted application.cfc I would have a licensing function that check the license for my code.

OK I can stop them decrypting the template but if they just dumped #application# they may be able to reconstruct all the vars/session variables etc.

Is there a way to stop this?

Reply to this Comment

@Phil,

While there are things that simply have to be available in the THIS scope, what you could do if you needed something hidden would be put in the VARIABLES scope of the Application.cfc and provide access to it via getter methods.

Of course, this is really only a minor fix as someone could always inject a tunnel into the Application.cfc to get all kinds of information about it. Heck, someone could even extend the Application.cfc object and view it that way (using CFDump and what not).

There's very little that is truly secure about actual ColdFusion files (from a server point of view). I've even worked with apps that had encrypted CFM pages that ended up including into other files with and working that way.

Reply to this Comment

This is the problem I'm finding. I'm currently using a tool to encrypt the entire contents of my code admin folder which I encrypts and password protects the encrypted file so it's "impossible" to decrypt.

I wanted, however, to move away from this and just encrypt the application.cfc and hide the licensing module in there...

Will have to give this some more thought...

Reply to this Comment

Actually I've figured it out :)

What I can do is encrypt the license sting stored in the application session var using an encryption salt that is known by both the application and the licensing server.

If the salt randomly changed each time then the license string would be different as well so even if the application.cfc was reverse engineered, the license string would never be the same.

Now to oput the theory into practice ;)

Reply to this Comment

@Samaotuo,

Thanks!

@All,

And, it should also be worth pointing out that in ColdFusion 10 (public beta), there is now an in-built method for accessing the application data - getApplicationMetaData().

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.