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() 2014 (Bloomington, MN) with:

Circumventing ColdFusion Component Security Using Dynamic Methods

By Ben Nadel on
Tags: ColdFusion

ColdFusion allows some really flexible stuff concerning swapping methods in an out of ColdFusion components at run time. I have talked about setting methods directly into components. I have also talked about passing in methods as component behaviors. Both strategies can create very dynamic, very flexible objects. On my way home last night, however, I realize that this flexibility can be used to circumvent all ColdFusion component security.

To explore this idea, let's create a Woman ColdFusion component who has some secrets that she doesn't want to get out:

  • <cfcomponent
  • displayname="Woman"
  • output="false"
  • hint="I am a woman... with secrets">
  •  
  •  
  • <!--- Run the pseudo constructor. --->
  • <cfscript>
  •  
  • // Set up private variables.
  • VARIABLES.Age = 40;
  • VARIABLES.Weight = 133;
  • VARIABLES.Hair = "Brunette";
  • VARIABLES.CupSize = "34B";
  •  
  • // Set up public variables.
  • THIS.Age = (VARIABLES.Age - 5);
  • THIS.Weight = (VARIABLES.Weight - 10);
  • THIS.Hair = "Blonde";
  • THIS.CupSize = "34C";
  •  
  • </cfscript>
  •  
  •  
  • <cffunction
  • name="Init"
  • access="public"
  • returntype="Woman"
  • output="false"
  • hint="Returns and initialized Woman instance.">
  •  
  • <!--- Return This reference. --->
  • <cfreturn THIS />
  • </cffunction>
  •  
  • </cfcomponent>

As you can see, the value for Age, Hair, and bust Cup Size that she advertises to the world are different from what is, in reality, going on behind the scenes. She subtracts 5 years from her actually age, 10 lbs from her actually weight, has died her hair, and inflates her boob size. But who can blame her? Men are so shallow. Unfortunately, she is thinking about what will make others happy, not what will make her happy.

But I digress... let's get back to the topic at hand. What if we wanted to know what the Woman's real descriptive properties were? We can't. Since they are stored in the VARIABLES scope, they are not accessible from outside of the component itself. We, as the general public, only have access to things stored in the THIS scope of the component.

Ok, but we really want in! What to do? Let's create a free-standing method that will act as a tunnel into the VARIABLES scope. It's free standing, so we can't run it on it's own, but let's assume that it will be part of component at some point. Assuming that, we can reference the VARIABLES scope in the method:

  • <cffunction name="Snooper" access="public" returntype="any" output="false"
  • hint="I can snoop behind the scenes in the VARIABLES scope.">
  •  
  • <!--- Set arguments. --->
  • <cfargument name="Action" type="string" required="false" default="GetVariables" />
  • <cfargument name="Name" type="string" required="false" default="" />
  • <cfargument name="Value" type="string" required="false" default="" />
  •  
  •  
  • <!--- Check to see which action we are going to perform. --->
  • <cfswitch expression="#ARGUMENTS.Action#">
  •  
  • <cfcase value="Get">
  • <cfreturn VARIABLES[ ARGUMENTS.Name ] />
  • </cfcase>
  •  
  • <cfcase value="Set">
  • <cfset VARIABLES[ ARGUMENTS.Name ] = ARGUMENTS.Value />
  • </cfcase>
  •  
  • <cfdefaultcase>
  • <cfreturn VARIABLES />
  • </cfdefaultcase>
  •  
  • </cfswitch>
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>

As you can see, this function either sets a VARIABLES-scoped value, gets a VARIABLES-scoped value, or, by default, will return the VARIABLES scope itself. Again, we can't run this on it's own due to the VARIABLES references. But, we can store it in another object due to the amazing run-time flexibility that ColdFusion provides.

First though, let's create a Woman object and get some values just to see what she's bringing to the market:

  • <!--- Create a woman instance. --->
  • <cfset Woman = CreateObject( "component", "Woman" ).Init() />
  •  
  • <!--- Get the woman's public properties. --->
  • Age: #Woman.Age#<br />
  • Weight: #Woman.Weight#<br />
  • Hair: #Woman.Hair#<br />
  • Cup Size: #Woman.CupSize#<br />

This gives us the following output:

Age: 35
Weight: 123
Hair: Blonde
Cup Size: 34C

As you can see, by default, we only get the values SHE wants us to see. Now, let's store the Snooper method inside of the Woman and get properties using Snooper method calls:

  • <!---
  • Store the Snooper method inside of the Woman's THIS scope.
  • This will make the Snooper method publically accessible
  • and still be part of the Woman object.
  • --->
  • <cfset Woman.Snooper = Snooper />
  •  
  • <!--- Get the woman's PRIVATE properties. --->
  • Age: #Woman.Snooper( "Get", "Age" )#<br />
  • Weight: #Woman.Snooper( "Get", "Weight" )#<br />
  • Hair: #Woman.Snooper( "Get", "Hair" )#<br />
  • Cup Size: #Woman.Snooper( "Get", "CupSize" )#<br />

This gives us the following output:

Age: 40
Weight: 133
Hair: Brunette
Cup Size: 34B

As you can see, the Snooper method gives us proxy access to the private scope of the woman. For all intents and purposes, we are now able to lift up this Woman's skirt and poke around even though she doesn't want us to.

Now, not only can we get and set private variables, we can also return the VARIABLES scope itself. If we store a reference to that, it is freely editable. Let's get the woman's private variables and force her public variables to be more truthful:

  • <!--- Violiate this woman by grabbing her privates. --->
  • <cfset ViolatedWoman = Woman.Snooper() />
  •  
  • <!---
  • Force her public properties to reflect her private
  • properties. She's beautiful and shouldn't be afraid of
  • how she looks.
  • --->
  • <cfset ViolatedWoman.THIS.Age = ViolatedWoman.Age />
  • <cfset ViolatedWoman.THIS.Weight = ViolatedWoman.Age />
  • <cfset ViolatedWoman.THIS.Hair = ViolatedWoman.Hair />
  • <cfset ViolatedWoman.THIS.CupSize = ViolatedWoman.CupSize />

Now that we have done that, if we run our original code accessing only her public values:

  • Age: #Woman.Age#<br />
  • Weight: #Woman.Weight#<br />
  • Hair: #Woman.Hair#<br />
  • Cup Size: #Woman.CupSize#<br />

... we get the following output:

Age: 40
Weight: 40
Hair: Brunette
Cup Size: 34B

There you have it; using dynamic-method run-time ColdFusion component flexibility, we can basically get at anything we want to. So, what are the implications of this? Well, they are only bad. No one needs to get at VARIABLES-scoped values unless they are up to shenanigans or maybe even some tomfoolery. The biggest concern I can see if for third-party software that requires registration keys during initialization. Even if a CFC is encrypted (which is not that secure anyway), this methodology would allow users to instantiate an object then go right into it and start messing around with registration flags.

One last thing: we can also get access to private methods this way as well. Let's go back and put in a private method for this woman to be able to go home and touch herself in a very adult way:

  • <cffunction
  • name="PleasureYourself"
  • access="private"
  • returntype="string"
  • output="false"
  • hint="Manual pleasure is a healthy part of anyone's life.">
  •  
  • <!--- Oh yeah baby. --->
  • <cfreturn "Oh oh oh oh oh oh yeah, oh oh, yeah, oh." />
  • </cffunction>

As you can see, this is PRIVATE. Only the woman herself knows about it. If we tried to call this directly:

  • <!--- Do it. --->
  • #Woman.PleasureYourself()#

... we get the error:

The method 'PleasureYourself' could not be found in component D:\....\kinky_solutions\site_v1\testing\snooper\Woman.cfc. Check to ensure that the method is defined, and that it is spelled correctly. <br>The error occurred on line 93.

However, assuming we got the ViolatedWoman object (as we did above), we can now call the pleasure yourself method via the ViolatedWoman reference:

  • <!--- Do it. --->
  • #ViolatedWoman.PleasureYourself()#

This gives us the output:

Oh oh oh oh oh oh yeah, oh oh, yeah, oh.

So, not only does this Snooper method give us access to the Private variables, it also gives us access to the Private methods. Nothing is safe.




Reader Comments

The CF "security" isn't really designed to secure things from the coder, but to protect the code from being used incorrectly--as well as to prevent unauthorized calls when invoked from a RPC/Web Service.

This is more of an awareness issue than an CF security issue.

If you ended up writing something like your Snooper function and had it public, then you could end up exposing information you intended to be private. I'd consider it a coding error--just like if you defined private data in the THIS scope.

Dan,

I agree with you 100%. That's why when I talked about implications, my only concerns were about 3rd party components that you could easily get into. When it comes to your own code, heck, shoot yourself in the foot if you want to. I understand that it's not really a security problem. I just thought it was an interesting outcome of the flexability that ColdFusion provides.

Ben,

I have to say that I'm very impressed by your posts. This is an extremely interesting topic your hitting into. I can think of a number of ways this could be used to write plugins for my existing application. I also like the suddle hints of sexual nature of your posts and your blog. Keep up the great work!

On a side note: You need to get laid. :)

ha ha ha ha ha ha :)

Tony, thanks for following the topics. I do have a GF, but my code makes me feel smarter the next morning :D

Dude... I have to minimize your site when my boss walks by at work! Great content and your examples are easy to follow, but I may have to AdBlock your images in Firefox. Your logo and bookmark icon are a bit much for corporate America :-) Keep up the good work and tone down the sex volume a little!

Steve,

I can tone down the volume... but I can't get rid of the logo. Heck, the logo was the first thing I designed on the site :)

Sorry but this is absolutely not a security issue.
In order to do this you need full access to the source code to insert your snooper function.
If you have full access to the code then you can do anything you like, as you should of course be able to.

This would only be an issue if you could extract the variables scope from someone else's CFC on the same server without having physical access to it.

Coldfusion would be a pretty useless language if it denied a developer access to every variable he created.

Russ,

I did not mean to say that this was a true security issue. I meant only to demonstrate that you could circumvent the "Access" settings of a given ColdFusion component on the fly. This is a form of security, but certainly not a very big one.

More than anything, I was just demonstrating how dynamic ColdFusion is (which is part of why is is so freakin, playa).

Just came across this example. Quite useful but this stuff:

<!--- Violiate this woman by grabbing her privates. --->

is pretty unpleasant.