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.
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?
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
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]
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
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?
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]
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
Interesting question, Elliot. I'll find out and post a reply here.
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?
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]
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]