BlueDragon Blog
Here you'll find tips and information about making the most of BlueDragon, which offers several compelling implementation alternatives for your CFML applications. This blog was created originally by Charlie Arehart, who was New Atlanta CTO from 2003-2006.,He has since moved on to become an independent consultant but continues to answer comments raised in existing blog entries. BlueDragon continues, and you should look to the newer BlueDragon blog, from New Atlanta president, Vince Bonfanti, for more updated information.

BlueDragon Advantage - Dynamically rendering CFML from a variable (or database column)

posted Tuesday, 21 December 2004

Some might expect that I'd lead the list of advantages with some of our strongest distinctions, but I'd rather start with some of the less well-known features that may intrigue the most CFML developers.

Many developers have long wanted to store CFML in a database column and then later process it. They've had to resort to clumsy steps. Gift #1 is a new Render function, due out in our 6.2 release, which will for the first time allow CFML developers to store CFML in a variable (or a database column, text file, etc.) and then render that CFML dynamically.

It may feel like a CFINCLUDE but it's much more, and designing it as a function gives more flexibility, including the ability to easily process (or ignore) its results, call it in a CFSCRIPT, and more.

Examples include the following:

    <cfoutput>#Render( someQuery.cfmlContent )#</cfoutput>

    <cfscript>
    writeOutput( Render( someQuery.cfmlContent ) );
    </cfscript>

    <cfset render(somecfmlcontent)>

As with a CFINCLUDE, any CFML in the variable is processed just as if it was running in the template that called it. Any variables you set inside this CFML will be available to the calling template, and path names for custom-tags and CFINCLUDE's will be relative to the calling template.

Just another way BlueDragon is helping solve real problems for the journeyman CFML developer.




1. a reader left...
Tuesday, 21 December 2004 7:22 pm

That's a double-edged sword if I've ever seen one. As if cross-site scripting attacks weren't bad enough, now it's possible to use the same mechanism for server executed code? Certainly circumventable through good coding practice, but then, so is XSS.

How does that work inside UDFs? Does the code execute as if it were included, or as if it were inlined in the function body?

Barneyb [bboisvert@gmail.com]


2. a reader left...
Tuesday, 21 December 2004 8:33 pm

now, this is going to be a wee bit dangerous. shoudlnt there be some code to instantiate it or disable it.

i think it is a feature that must be used judiciously.

Adedeji Olowe


3. a reader left...
Tuesday, 21 December 2004 11:22 pm

I think the main "use case" for this is rendering CFML that's taken from a database, not rendering user input from a form field (which is what you'd need for a cross-scripting type attack). As long as there's no user input involved, there shouldn't be any security concerns.

Vince Bonfanti [vince@newatlanta.com]


4. a reader left...
Wednesday, 22 December 2004 8:30 am

Vince (and Charlie), I agree it is safe if it is from the db, but you have to admit this is potentially dangerous. I'd just be sure to make the docs -super- clear on this.

Raymond Camden


5. Charlie Arehart left...
Wednesday, 22 December 2004 11:54 am

Guys, people have been asking for this feature for years, and never have I heard anyone raise these concerns.

Let me ask you all: is there some approach you would have envisioned for solving this long-requested feature that wouldn't have these concerns?

And as for warning people, should we also warn them not to do a DELETE without a WHERE clause in a CFQUERY? Or to be careful about how some system command can be run with CFEXECUTE?

Seriously, this is server-side processing, guys. I don't see how it's like cross-site scripting at all.

What sort of warning would you propose?


6. a reader left...
Thursday, 23 December 2004 5:24 pm

By the way, this is no different than the "security hole" presented by CFQUERY. For example, you'd never do something like this:

<cfquery ... >
#Form.UserInput#
</cfquery>

Similary, you'd never do this:

<cfoutput>#Render( Form.UserInput )#</cfoutput>

Vince Bonfanti [vince@newatlanta.com]


7. a reader left...
Saturday, 1 January 2005 3:06 am

Great feature guys - i have wanted this sort of power for years. It is no more dangerous than connecting your computer to the internet!

At the moment i do a file write followed by a cfinclude. What is the performance like - any kind of tricks to avoid compilation each and every time even when no change to the source perhaps a hash of the string mapped to the class file?

Elliot

Elliot Russo


8. Charlie Arehart left...
Saturday, 1 January 2005 12:25 pm

Interesting question, Elliot. I'll find out and post a reply here.


9. a reader left...
Tuesday, 11 January 2005 9:33 pm

I think what people are saying is that maybe there should be some options to limit the execution rights the function had (like a sandbox)... Perhaps...


Render( someQuery.cfmlContent, "CFINCLUDE,CFLOCATION")

I know that the only tag I care to evecute from DB is CFINCLUDE. I don't immagine folks will want to execute CFFILE or CFQUERY, but then again, it is up to them. At least CFQUERYPARAM allows for some protection.

Otherwise, Very very cool. Will you be able to demo this functionality in February?

Igor [bd@maverickmaven.com]


10. a reader left...
Wednesday, 12 January 2005 11:40 am

First, to Elliot, who had concerns about performance, the engineer's response was that speed should not be an issue. BD compiles so quickly, but I realize others may want more (or more control). For now, let's just wait and see what comes of it from people's use.

Second, to Igor, as for security, let's first clarify that while BD doesn't have the sandbox security mechanism of CFMX (per se), it is possible to restrict the access for all tags/functions in a CFML app when deployed on a J2EE server or the .NET framework by way of built-in mechanisms they both offer. That's not a BD feature, specifically, but it does alleviate the need for us to worry about the issue. Those who need it can enable the native web app security measures to control what's allowed in such web apps.

Along the same lines, we'd also argue that anyone with a concern for how this function might be used could also impose limits using those mechanisms.

We do not currently offer the kind of tag/function disabling features that CF offers. Like a handful of other things, it would be nice, but no customer (or potential customer) has made it a priority concern. We don't just add things to keep up, even when (as in this case) it might be argued to be a good idea. We have to be smart about how we allocate resources. (The same could be said to argue why MM hasn't added a CFIMAGE, CFIMAP, or CFZIP tag in the past: good ideas, but not urgent to their customers, though they were to ours, so we added them.)

Again, time will tell how things evolve. Certainly, if any untoward issues arise from this new feature, we will address them.

Finally, as for February, Igor is referring to my coming to speak at the Chicago CFUG in February. Igor, I don't know that I would have gotten to that specific feature in a presentation, but I could certainly show you if you're interested.

charlie arehart [charlie@newatlanta.com]


11. a reader left...
Thursday, 20 January 2005 10:38 pm

It's no safer coming from a database than it is coming from a URL. The origin of the cfml code is not important, it's whether or not it was entered by a user.

For example, only a fool would use the Render() function in any situation where the data being pulled from the database is dynamically created by an end user.

Heck, I have to remember to use my tagStripper() function on just about all user input... lord knows I don't want people putting html tags in their usernames, etc.

Like any feature, it's safe when used properly. And could definately come in handy.

Rick Root [rick@webworksllc.com]