Evaluating Database Records That Contain ColdFusion Interpolation Expressions In Adobe ColdFusion 2018
Yesterday, I was talking to Angel Gonzalez about an interesting use-case in ColdFusion - something that I've never personally tried before - evaluating database records that contain ColdFusion Expressions. Specifically, database records that contain String interpolation in which the interpolated value is being pulled out of the current ColdFusion request. I'm always curious to see how the CFML runtime can be used to unique ways; so, I thought I would try this out for myself.
The idea here is that the database record would contain a varchar
value like:
Hello, #name#
... in which the dynamic name
value would be pulled out of the ColdFusion request at runtime and interpolated as part of a dynamic evaluation.
In ColdFusion, we can use the evaluate()
function to execute "stringified" ColdFusion code. Which usually goes hand-in-hand with the de()
function for "Delayed Evaluation". So, to try this out, I created an in-memory Query object and then ran it through the evaluate()
function:
<cfscript>
// Let's create a database query that contains ColdFusion Expressions that will be
// evaluated at runtime in the context of a particular request. In this case, each
// "message" value contains a variable interpolation.
records = queryNew(
"id,message",
"integer,varchar",
[
// NOTE: We are using double-hashes "##" here in order to embed a single
// hash in the derived String value.
{ id: 1, message: "##request.prefix##Good morning!" },
{ id: 2, message: "##url.prefix##Good afternoon!" },
{ id: 3, message: "##form.prefix##Good evening!" },
{ id: 4, message: "##variables.prefix##Good morrow!" }
]
);
// Our four database records will pull from four different ColdFusion scopes.
request.prefix = "Hello Angel, ";
url.prefix = "Fine sir, ";
form.prefix = "My man, ";
variables.prefix = "Yo yo yo, ";
cfloop( query = records ) {
writeOutput( "Evaluating: <strong><code>#records.message#</code></strong>" );
writeOutput( "<br />" );
// The evaluate() function dynamically evaluates a string of COLDFUSION CODE.
// However, if we try to evaluate the message AS IS, it will throw an error
// because it will interpret the string as raw ColdFusion syntax tokens. As such,
// we have wrap the String in a DELAYED EVALUATION (de) call.
writeOutput( evaluate( de( records.message ) ) );
writeOutput( "<br />" );
// The de() call is really just wrapping the string in quotes so that the "code"
// being interpreted is a String and not a raw series of ColdFusion tokens. To
// see this equivalence, we can remove the de() call and add our own quotes:
writeOutput( evaluate( """" & records.message & """" ) );
writeOutput( "<br /><br />" );
}
</cfscript>
As you can see, each message
query-column contains a String-interpolation expression which references a value stored within the ColdFusion request context. And, when we run this ColdFusion page, we get the following output:
As you can see, we were able to evaluate each database query column value as if it were a line of ColdFusion code that referenced variables stored within a variety of scopes.
ColdFusion is just a fascinating language! It's so incredibly dynamic that it's rare that I come up against a use-case that can't be implemented in some way. I don't personally have any use-cases where I've needed to store ColdFusion "code" in a database; but, at least to some degree, this is totally doable.
A Note of Caution On Security
In this case, the assumption here is that the application is the one generating the CFML expression to be evaluated at a later time. As such, this is a safe approach. However, you would never ever want to dynamically evaluate code that is provided by the user in any way. That would open you up to a whole host of security problems!
For example, in this exploration, I am pulling some of the variables from the URL
and FORM
scopes. In the "real world", this would be heavily problematic as this would leave you open to Reflected XSS (Cross-Site Scripting) attacks (since the user can populate the URL
and FORM
scopes with malicious data).
Want to use code from this post? Check out the license.
Reader Comments
Thank you Ben - it's always a pleasure to talk to you in any context but I can attest, when it comes to ColdFusion... it's Jedi's at work! (sorry Ray Camden). I'm sincerely grateful for the knowledge you spread once you delve into work.
I'm going to use some of those variables and say... yo yo yo, my man, Thank you Fine sir for your awesome work.
Now I have to code a bit and get this going with some excellent ideas I have on how to use it!
@Angel,
Ha ha, my pleasure, good sir!