Entries Tagged as 'ColdFusion'

CFSelenium Now Compatible With ColdFusion 7 and 8

CFML , ColdFusion , Selenium No Comments »

A few weeks ago, Bob Silverberg released his latest open-source project, CFSelenium.  For those who don't know about the project, a little background:  Selenium is a tool suite for testing web pages.  The most well-known member of the Selenium product family is Selenium IDE, a Firefox plugin that lets you record the actions performed on a web page (or a series of connected web pages) and the results of those actions.  You can then use the recording (stored as a series of commands) to redo those steps whenever you need to test the page or pages after making changes.  Another member of the Selenium product family is Selenium Server (formerly called Selenium-RC), which is a small, Java-based server that can run scripts comprised of Selenium commands in multiple browsers, allowing you to conduct the same kinds of tests recorded by Selenium IDE in browsers other than Firefox:  a great way to test web page functionality across multiple browsers.

In creating CFSelenium, Bob made it possible (easy, in fact) to create and run Selenium Server scripts using ColdFusion 9, and created a plugin for Selenium IDE that would output the recording statements in CFSelenium format within MXUnit test case functions.

Bob wrote CFSelenium in ColdFusion 9-compatible cfscript, and after he announced the project a few folks inquired about the possibility of having a version written in tag-based CFML.  On somewhat of a whim, I decided to take on that task, and ended up with a tag-based version of Bob's original selenium.cfc file that is compatible with both ColdFusion 7 and ColdFusion 8, as well as a few test files that run against the tag-based version.

Bob has now incorporated my tag-based version and my test files into the CFSelenium project, and we've agreed that I will maintain the tag-based version while he maintains the CF9 script verison.  You can download CFSelenium from either RIAForge (http://cfselenium.riaforge.org/) or from GitHub (https://github.com/bobsilverberg/CFSelenium).  For more about Selenium in general, I'd suggest reading Bob's blog post announcing CFSelenium as well as the Selenium website.

So if you're a developer whose responsibilities include cross-browser testing of your web pages, you should really check out CFSelenium.

When TimeFormat() Can't Quite Give You What You Need

CFML , ColdFusion 6 Comments »

So today I got a call from one of my clients.  The app we built for her is an event management app, and one of its functions outputs a list of all the events, including the start and ending times for each event.  Those times are output using ColdFusion's TimeFormat() function like so:

#TimeFormat(event.startTime,"h:mm tt")# - #TImeFormat(event.endTime,"h:mm tt")#

...which (for example) comes out as:

10:00 AM - 1:30 PM

My client was calling because she was told (by the local style enforcer, I guess) that the university's publishing style dictates dropping the ":00" for times that start on the hour and to use "a.m." and "p.m." rather than "AM" or "PM".  She wanted to know if I could adjust the report output to meet the style.

I briefly tried to see if there was a way to change the mask parameters in TimeFormat() to get the desired format, with no luck.  A quick search online for a ready-made solution also didn't yield any results.  So I ended up doing this:

<cfset initialVals= "AM,PM,:00">
<cfset newVals= "a.m.,p.m.,">
...
#ReplaceList(TimeFormat(event.startTime,"h:mm tt"),initialVals,newVals)#
- #ReplaceLIst(TimeFormat(event.endTime,"h:mm tt"),initialVals,newVals)#

That did the trick, but if someone's got another way of handling it, please feel free to share.

Technique For Managing Form Input in Model-Glue

ColdFusion , Model-Glue No Comments »

I've been meaning to post about this technique I'm using in some of my Model-Glue applications, but I couldn't decide on the best way to explain what led me to develop it.  So I'm going to start with the code first rather than the explanation:

<cffunction name="collectFormDataAndTrim" access="public" returntype="void" output="false" hint="I collect the form values">
    <cfargument name="event" type="any">
    <cfset var loc= StructNew()>
    
    <cfset loc.propertyList= arguments.event.getArgument("propertyList","")>
    <cfif loc.propertyList EQ "">
        <cfset loc.propertyList= arguments.event.getValue("fieldnames")>
    </cfif>
    
    <cfset loc.form= StructNew()>
    <cfloop index="loc.prop" list="#loc.propertyList#" delimiters=",">
        <cfset loc.propValue= arguments.event.getValue(loc.prop)>
        <cfif IsNumeric(loc.propValue)>
            <cfset loc.form[loc.prop]= loc.propValue>
        <cfelse>
            <cfset loc.form[loc.prop]= Trim(HTMLEditFormat(beans.miscService.removeMSWordChars(loc.propValue)))>
        </cfif>
    </cfloop>
		
    <cfset arguments.event.setValue("form",loc.form)>
</cffunction>

 

This collectFormDataAndTrim function lives in my main controller CFC in my Model-Glue appplications. I call it via a message broadcast any time I need to process typical form input.

Like many of the ColdFusion application frameworks, Model-Glue takes both the URL variables and any values submitted by an HTML form and puts them into one data structure for easy retrieval.  In the case of Model-Glue, that data structure is the event object. My function supports two different methods for retrieving the form values from the Model-Glue event object: it can use the list of form field names contained in the "fieldnames" variable created by ColdFusion, or it can process the event variables named in an argument called "propertyList" submitted in the message broadcast, like so...

<broadcasts>
    <message name="collectFormDataAndTrim">
        <argument name="propertyList" value="firstName,lastName,email,acceptTerms" />
    </message>
...

 

Two reasons for the propertyList option: specifying the form fields you expect to get prevents you from processing extra form fields a malevolent user might add to the form via JavaScript or some other means, and it allows you to name checkbox fields which would not be included in the formfields list if the user doesn't check them.

Once the form fields names are copied into the local propertyList variable, the function loops through the form variables, sanitizes them for further processing using Trim() and HTMLEditFormat(), and adds them to the loc.form struct variable.  I also submit the non-numeric form values to the removeMSWordChars function in my miscService bean to replace any Microsoft Word characters within the content with web-friendly equivalent values (my users have an annoying habit of copying and pasting text from Word into longer text fields).

Finally, the loc.form struct variable containing the santized form submissions is saved back into the Model-Glue event object to be utilized by subsequent message broadcasts (for the functions that will validate the form data and save it to the database).

Preventing CSRF Attacks Using Event-Types in Model-Glue

ColdFusion , Model-Glue 1 Comment »

A cross-site request forgery (CSRF) occurs when a hacker takes advantage of the fact that users don't always log out of the websites and web applications they visit. The hacker creates a URL or a form that passes valid data to a valid destination on the target website and hopes that a user who is still authenticated to that website clicks that malicious URL or form. If such a user falls into the trap, the target website will process the request just as if the user had executed the action within the target website under normal circumstances.

One common method for preventing CSRF attacks is to generate a unique value every time a user visits a form on the website and store that value both within the user's session and within the form itself as a hidden field. When the form is submitted, the value in the form is checked against the value stored within the user's session, and if they don't match the form submission isn't processed. The next time the user encounters a form (even if it's the same form), a new unique value is generated. Without a way of knowing what that unique value is at any given time, the hacker cannot build a form or construct a URL that simulates a legitimate request, and the attack fails.

Rather than have to remember to create these unique values and include them within every form (or every URL that executed some sort of data operation), and then check the validity of the submitted value on each processing page, I wanted to see if there was a way I could build CSRF security into the structure of my Model-Glue applications.

Read more...

Quick Tip: Securing Your Model Glue XML Configuration Files

ColdFusion , Model-Glue 2 Comments »

A quick disclaimer: nothing I'm about to say here is all that revolutionary.  Others, particularly Charlie Griefer, have posted about this technique before, just not with a specific focus on using it with Model-Glue or with exact step-by-step instructions.

There are a number of key configuration files in Model-Glue that exist as plain XML files. One of the drawbacks to using XML files on a website is that anyone can point their browser at the XML file and read its contents, which is less than ideal from a security standpoint.

There are a number of ways you can make those XML files secure, such as storing them in a directory outside of the web root or configuring your web server to block access to XML files (see Charlie's post for details on those techniques), but not every developer has the permissions needed to implement those solutions.

So one way that you can protect those XML files without needing access to anything beyond the web root is to convert them to .cfm files and prevent them from executing, and here are the exact steps you would use in a typical Model-Glue application to do just that:

  1. Go to the index.cfm file of your application.  Uncomment the <cfset> line for "CUSTOM APPLICATION CONFIGURATION" and set it to point to "Coldspring.xml.cfm" instead of "Coldspring.xml".
  2. Rename "ColdSpring.xml" to "ColdSpring.xml.cfm". 
  3. In the ColdSpring file, go to the ModelGlue configuration bean definition and change the "configurationPath" and "scaffoldPath" values to point to the .cfm equivalent files instead of the original XML ones.  If you're using Transfer or Reactor in your application, also update any <constructor-arg> tags in those bean definitions that point to the XML configuration files for those ORM frameworks.
  4. If you have any other references  to .xml files in your ColdSpring file, update those as well.
  5. In the ModelGlue.xml file in your application, remove "<cferror>" from the comment above the "page.error" event (if you don't, anyone who does try to browse to that file will generate a ColdFusion error).
  6. Tack on ".cfm" to the file names of all of the .xml files referred to in steps 3, 4, and 5.
  7. Add an Application.cfm file to the "config" directory of ModelGlue with one line in it: <cfabort />  That will ensure that the XML is not shown even in the page source if the .xml.cfm file is directly accessed by the browser.

The end result of taking these steps is that if anyone tries to point their browser to any of these renamed configuration files (ModelGlue.xml.cfm, ColdSpring.xml.cfm, etc.) all they will get back is a blank page with no source code to view.