Sunday, November 28, 2010

Technique For Managing Form Input in Model-Glue

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:

 

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).

Wednesday, September 1, 2010

Custom jQuery Validate Rule For Making Sure One Date is Later Than Another

In addition to providing a number of standard validation rules, the jQuery Validation plugin also allows you to create your own validation rules via the addMethod() function.  Today I had a situation where I had to use that function:  I had to create a rule to ensure that the end date of a date range determined by the user was later than the starting date.  I thought I'd share what I came up with.

The details of the situation:

  • The user set the starting date using two radio buttons and a text field bound to the jQuery UI Datepicker.  Selecting the first radio button meant that the start date (the "now" button) should be set to the current date, while selecting the second radio button (the "later" button) meant that the starting date would be determined by the value in the Datepicker field.
  • The user set the ending date using another Datepicker-bound text field.
  • The Datepicker plugin ensures that the date is always in the format "mm/dd/yyyy".

Here is the code:

 

So if the user selected the second start date option and chose a date using the Datepicker widget, the code splits up the date string into an array and uses the individual month, day, and year values to create a Date object. If the user selects the option of making today the starting date, a new Date object is created (which by default has the value of the current date and time) and the code creates a new Date object with the same date but with the time-specific data stripped out (because the end date will not have a time value attached to it).

The Date object for the end date is created with the same technique used for the second start date option, and then the getTime() function is used on both the start and end Date objects to get the number of milliseconds between each date and January 1, 1970 (a starting point for date and time values used in both JavaScript and Java). Then it does the comparison between the two dates.

It's then a simple matter of applying this custom method somewhere within the normal jQuery Validation rules block:

...
rules: {
    endDate: {
      required: true,
      dateComparison: true
    }
...

Tuesday, June 29, 2010

Quick Tip: Use jQuery live() Function For Links in JavaScript-Powered Data Tables

NOT doing the tip that I'm about to share has bitten me twice now, so I'm putting this out there as a reminder to myself as well.

The jQuery live() function is an extremely useful function to have when you're adding or removing page elements that have jQuery event handlers assigned to them because using live() ensures that any new element that matches the live() selector gets that event handler automatically.

It's easy to remember to use live() when you're writing your own code that adds and removes DOM elements, but when you're using a plugin that does the adding and removing behind the scenes, you might not think about it.  In one of my applications, I apply the jQuery DataTables plugin to my HTML tables so that the users can sort and filter the data in the tables.  Included in each row are hyperlinks that trigger certain actions via JavaScript/jQuery. 

When I originally assigned the event handlers to these links, I simply used the "click" event handler on them.  The links worked perfectly if they were displayed as part of the initial page load, but any links belonging to rows that appeared later (as the result of a sort, filter, or pagination event in the plugin) did not work because the link elements were actually added by the plugin, and hence did not have the event handlers assigned to them.

In short, if you're using one of the many plugins to enhance HTML tables, and you have elements in each row that have jQuery events assigned to them, make sure you use the live() function to assign those event handlers.

Monday, June 28, 2010

My First Published Android App: NoteToSelf

I haven't been blogging much lately, but that's partly because I was on vacation for a week and partly because I was working on this:

https://play.google.com/store/apps/details?id=org.swartzfager.NoteToSelf

It's a fairly simple app built with the standard Android API, but it meets MY need for a note/reminder list that is right there on my Android home screen and lets me see all of my reminders without having to go into the application. And being able to dictate my reminder (I put in the dedicated dictation button because my Swype keyboard doesn't have a key for dictation like the stock Android keyboard does) makes it easy to add a quick note if you can tolerate a mistranslation here or there.

This version is free, so if you have an Android device running 2.1 or higher, feel free to check it out.

Monday, June 14, 2010

Preventing CSRF Attacks Using Event-Types in Model-Glue

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 on a website they control that passes valid data to a valid destination on the target website and hopes that a user who is still authenticated to that target 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.

First, I wrote two new controller functions in my authentication/authorization controller CFC:

The secureTransmissionURL() function looks to see if there is a variable named "token" stored within the event object (for those unfamiliar with Model-Glue, the event object serves as a container for all of the variables associated with the request, including form and URL variables).  If no token variable exists in the requet, a variable named "token" is created or updated within the session scope and given a unique UUID value.

In the final line of the secureTransmissionURL() function, a new variable called "secureMyself" is created within the event object, and is given a value that serves as the starting point for any URL I want to protect against CSRF attacks within my Model-Glue application. This line deserves a bit of background information...

In Model-Glue (as with many of the ColdFusion frameworks), all requests run through the index.cfm page, and you dictate how the request should be routed by adding a particular variable (called the "eventValue" variable in Model-Glue) to the URL. In Model-Glue, the default name for that variable is "event," so if you kept that default, the URLs you would use to navigate within your Model-Glue application would look like this:

index.cfm?event=deleteRecord&recordId=12

Because it is possible to change that eventValue variable name from "event" to something else ("action", "goto", etc) with a simple change to the Model-Glue configuration settings in your application, it's not safe to hard-code "index.cfm?event=" into your URLs in your pages. So the standard practice is to use an event variable automatically provided by Model-Glue called "myself" to build your URLs. So instead of writing out "index.cfm?event=mainMenu", you would do something like this on your web page:

<cfset deleteRecordURL= event.getValue("myself") & "deleteRecord">
<cfoutput>
...
<a href="#deleteRecordURL#&recordId=12">Delete record 12</a>
...
</cfoutput>

(Note: normally the name of the event/event handler, in this case "deleteRecord", would actually come from an event variable as well, but I wanted to keep my example simple)

The "secureMyself" variable created in that final line of secureTransmissionURL() serves as a CSRF-secured alternative to the "myself" variable provided by Model-Glue. It adds the hashed value of the UUID value stored in the session scope to the "token" URL variable in front of the eventValue variable in the URL string, allowing me to use "secureMyself" to build my URLs in place of "myself" where needed (note: I would still use "myself" to build URLs that don't directly process data, such as a URL that sent the user to a menu page):

<cfset deleteRecordURL= event.getValue("secureMyself") & "deleteRecord">
<cfoutput>
...
<a href="#deleteRecordURL#&recordId=12">Delete record 12</a>
...
</cfoutput>

When the secured URL is rendered by ColdFusion, it ends up looking something like this:

index.cfm?token=524606212847B725A8AD313DD466CDCF66F8FC22B49DC31D525D51FC33B1E297&event=deleteRecord&recordId=12

The second function, the validateTransmissionURL(), is meant to be executed prior to processing a CSRF-secured page request. It checks to see if a token variable was included in the request, and if so it checks if the value of the submitted token matches the hashed value of the token variable stored in the session. If either of those conditions fail, a result of "invalidTransmission" is added to the event object, which effectively prevents the request from proceeding to the code that processes the request (that interacts with your persistent data).

After adding these two functions, I then incorporated them into my application using the following two event types:

If you're unfamiliar with event types in Model-Glue, I encourage you to read the documentation on the Model-Glue wiki. In my application, all of my event handlers that are only accessible to the user after they've authenticated/logged in are wrapped with the "permitted" event type defined above. By adding a message broadcast that calls my secureTransmissionURL() controller function to that event type, I ensure that the "secureMyself" event variable is available to use on all of my authenticated view pages.

The "validateTransmission" event type, which will make sure that the submitted URL contains the proper token value, will be applied only to my event handlers that process a form submission or execute a database transaction based on URL variables submitted in the request.  If the token is missing or incorrect, Model-Glue redirects the action to the "invalidTransmission" event handler, which will react to the possible CSRF attack. My "invalidTransmission" event handler presents an normal error message to the user (as it's the user, not the hacker, that will see the result of the attack) but notifies me that a possible CSRF attack has occurred.

Once I had these controller functions and event types in place, all I needed to do to secure my forms and hyperlinks against CSRF attacks was to use the "secureMyself" event variable to build the URLs for those forms and hyperlinks and to add the event type "validateTransmission" to those event handlers that processed submissions from those forms and hyperlinks.

If you want to learn more about securing against CSRF attacks, I would recommend that you read some of the blog posts that helped me understand CSRF attacks:

http://shiflett.org/articles/cross-site-request-forgeries

http://www.mollerus.net/tom/blog/2009/01/an_easy_block_for_crosssite_request_forgeries_csrf.html

http://www.12robots.com/index.cfm/2008/8/25/Request-Forgeries-and-ColdFusion--Security-Series-9

http://www.12robots.com/index.cfm/2009/2/9/Enhancing-Request-Forgery-Protection--Security-Series-91

Thursday, May 20, 2010

Quick Android Development Tip: Reusing Layouts With Includes

My last few Android development posts have been kind of long (took long to write anyway), so here's a short one...

When you develop websites, you often end up with a lot of pages that all share a certain block of layout or content. You would typically handle this by making a single separate file for that global content and pulling it into the other pages via some sort of include mechanism (virtual include, <cfinclude>, etc.).

Well, you can do the same thing in Android: you can create a separate layout XML file (say, for a header or a menu bar) and then include it in your other layout files, like so:

 

Wednesday, May 19, 2010

Defining Other Global Resources in Your Android Application

In my last post, I talked briefly about how the R.java file, a resource file located in the "gen" folder of your Android application project that is automatically generated and updated by Eclipse and serves as a resource map. My example code demonstrated how you could reference layout.xml files via the R.java file and how Eclipse would register the id of the UI objects within the R.java file as well.

I also mentioned that the layout XML files for your Android app are located in a "layout" folder within the "res" ("resources") folder.  There are other folders under the "res" folder as well, and the content within those folders is also registered with the R file, allowing you to access those resources within your Android code.

Here's a screenshot of what the "res" directory of my current Android project looks like:

The first three folders are "drawable" folders where you put any images you want to use in your application. As I alluded to in an earlier post, Android supports different screen resolutions through the concept of density-independent pixels, in that higher-resolution screens have a larger number of pixels per inch than a lower resolution screen (you can read more about how that works on the "Supporting Multiple Screens" page on Android Developer website).  The three different drawable folders allow you to have three different copies of the same graphic (with the same filename), one for high density/resolution screens ("hdpi"), one for medium density screen ("mdpi"), and one for low density screens ("ldpi").  So if I place a copy of a graphics file called "blueBox.png" in each of the drawable folders, I can reference it in my Android code via the filename (minus the extension) like so:

R.drawable.blueBox

...and (unless I've specifically said my application will only work with a certain pixel density) Android will take care of figuring out which copy of the image file it should display.

We can skip the "layout" folder since I've already talked about how to reference layout files in my previous post, so that leaves the "values" folder.

The first file in my "values" folder is colors.xml.  In Android, you're encouraged to record the color codes of your UI elements in this file (which you have to create).  Here's what the XML looks like:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pageColor">#fff</color>
    <color name="normalTextColor">#000</color>
    <color name="listItemColor">#333</color>
    <color name="goodColor">#009900</color>
    <color name="badColor">#ff0000</color>
</resources>

...so if you wanted to make a view object in your layout have the "pageColor" background (white, in this case), you'd reference it in your layout XML like so:

<ListView android:id="@+id/android:list"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@color/pageColor" />

The "@color" sign tells Android that we're referencing a color name registered in the resource file, so it knows how to retrieve the value. And again, you can reference these color values in your code (in case you want to change the color of an element or some text in response to some change or condition):

mStatusText.setTextColor(R.color.goodColor);

The second file in the "values" folder is strings.xml. As you can probably guess, it's meant to hold string values that you might use in one or more places in your application, things like screen headers or form labels. But it can also be used to define arrays of strings for use in scrollable lists or drop-down controls (like a list of U.S. states). Here's what it looks like:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">To-Do List</string>
    <string name="empty_list_message">There are currently no items</string>
    <string-array name="priority_choices">
     <item>High</item>
     <item>Normal</item>
     <item>Low</item>
    </string-array>
    <string name="delete_button_text">Delete</string>
    <string name="save_button_text">Save</string>
</resources>

You would reference a string resource much as you would a color resource, using "@string/app_name" as an attribute value in your layout XML or referencing the string programmatically using "R.string.app_name". To reference a string array, however, you'd use "R.array", as in "R.array.priority_choices", in your Android code (I'm not sure if there's a scenario in which you could reference a string array in your layout).

Finally, there's one more type of resource you can define in an XML file in the "values" directory: styles. I haven't used styles in any of my Android projects yet, but according to the "Applying Styles and Themes" page on the Android developer website, you can create a <style> block in XML that sets values for various visual attributes of view objects (size, typeface, font size, etc.) and then apply that entire set of attributes to a view object in your layout.