YOUR FEEDBACK
José D'Andrade wrote: "...it may never be released..." Why? "...if Midori isn’t heir to Windows Mi...
AJAXWorld RIA Conference
$300 Savings Expire August 8
Register Today and SAVE!


2007 West
GOLD SPONSORS:
Active Endpoints
Your SOA Needs BPEL for Orchestration
BEA
Virtualized SOA: Adaptive Infrastructure for Demanding Applications
Nexaweb
Overcoming Bandwidth Challenges with Nexaweb
TIBCO
What is Service Virtualization?
SILVER SPONSORS:
WSO2
Using Web Services Technologies and FOSS Solutions
Click For 2007 East
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
SYS-CON.TV
TOP COLDFUSION LINKS


Expect The Unexpected
Expect The Unexpected

No one wants to write buggy code, at least no one I choose to know. Bugs are annoying, bugs are embarrassing. And bugs can cost you (and your clients) lots of time and money.

Bugfree code is the ideal all developers strive for - at least should strive for - but it's a lofty goal not easily attained.

To write bugfree code it's important to understand how bugs are introduced. I'd like to explore what I believe to be one of the primary causes for the introduction of bugs into your code: failure to expect the unexpected. While many of these ideas apply to application development in general, the positioning of this column relates specifically to ColdFusion.

Flow? What Flow?
Applications are designed with a particular program flow in mind. Users start at point A, go to point B, then to point C. Program flow is an important part of any application, and when developers write they anticipate a particular program flow.

Here are some examples.

  • A search dialog is displayed, the user enters search criteria, a search is performed and the results are displayed.

  • The user browses a product catalog, makes multiple selections with possible confirmations and provides payment information, after which the order is saved and processed.

  • A login screen is displayed and the user provides authentication information, which is validated against a database. If authenticated, access is granted; otherwise the login screen is redisplayed.

    In each of these examples there's a logical starting point, then a series of steps. The search dialog must be displayed before the search can be performed, users must select items from the product catalog before the order can be processed, and login information must be provided before access can be authenticated.

    In traditional application development, programmers had total control over program flow. Users had no way to access screens out of order, nor could they start from a screen other than the one they were supposed to start at. But Web applications, for better or worse, behave differently. As every Web page has a unique address (its URL), it's indeed possible for users to execute pages out of order, just as it's possible for them to start from the wrong page.

    How could this occur? There are several ways. Users could bookmark pages directly, search engines might index pages below your root, and newer browsers feature an auto-fill option that completes URLs for users but frequently uses the most recently visited page in the site (often the wrong page).

    To understand this better, look at the following code:

    <!--- Perform search --->
    <CFQUERY DATASOURCE="ds" NAME="search">
    SELECT title FROM books
    WHERE title LIKE %#FORM.title#%'
    </CFQUERY>
    <!--- Create page --->
    <HTML>
    <BODY>
    <H1>Search Results</H1>
    <UL>
    <!--- Display search results --->
    <CFOUTPUT QUERY="search">
    <LI>#title#
    </CFOUTPUT>
    </UL>
    </BODY>
    </HTML>

    What's wrong with the above code?

    Actually, this is fairly typical ColdFusion code (it's even commented). It performs a simple database search and displays the results. The search itself is driven by a form that contains a field named "title"

    And that's what's wrong. The code makes two dangerous assumptions - that the page will be called from a form and that the form contains a field named "title". If either assumption turns out to be incorrect, ColdFusion throws an error because #FORM.title# would refer to a variable that didn't exist.

    What's the solution? There are a couple of things you can and should do. The first is always check for the existence of variables before using them, initializing them with default values if needed. The ColdFusion <CFPARAM> tag is very useful for this, and good programming practices demand that every variable be initialized this way so they always exist (either as submitted FORM or URL values, or as locally created variables). If the following code were inserted above the code example, the page would always execute correctly, regardless of how it was invoked and what fields were passed:

    <CFPARAM NAME="FORM.title" DEFAULT="">

    Sometimes you may not want to use default values. For example, in the preceding code you may not want to display the entire contents of the table if the page is executed directly. If a user ends up on this page without having filled in the form to perform the search, you'd want to send them to the search page instead. Here's one way you could do this (assuming the search page was named search.cfm):

    <!--- Is form field present? --->
    <CFIF NOT IsDefined("FORM.title")>
    <!--- Not present, redirect to search screen --->
    <CFLOCATION URL="search.cfm">
    </CFIF>

    With this snippet at the top of the page your code is now safe. If users try to execute the page directly, you'll programmatically redirect them to where they really should be.

    The truth is, every page on your site should be written so that it's safe to execute directly. That way you'll never make assumptions about program flow, and your code won't break when the unexpected occurs.

    Are you up for a challenge? How about writing code that uses <CFDIRECTORY> to traverse your code tree to find all CFM pages, then looping through each one, executing it via <CFHTTP> to see which ones throw errors and which work. You could call this code daily (or weekly or monthly) and e-mail yourself the results so you'll know as soon as possible if things might break.

    Changes in Site Usage
    Another phenomenon that's part of Web site use is the frequency with which that use changes. Programmers anticipate that their site will be used in one way, but, inevitably, users find another way to use it. That's not a bad thing in and of itself, but it does present an interesting problem.

    All applications, not just Web-based applications, are designed so that particular parts perform better than others. This is usually because certain parts of the application are more critical and get more use, so the time and effort needed to improve and enhance the site tends to be best spent on these parts.

    The application hums along nicely, handling the load thrown at it, and everything works well until those pesky users start using your site in ways you didn't expect. Suddenly the efficient and highly optimized parts are being executed less and less, and the less fine-tuned (I'm being generous) parts start to buckle under the growing load.

    This is actually a very common problem. Some of the largest and most impressive sites on the Internet have fallen victim to it.

    The good news is that ColdFusion provides you with an invaluable (and frequently overlooked) tool you can use to identify these potential trouble spots. The ColdFusion Administrator (starting in version 4) features a checkbox that, when checked, allows you to log page requests that take longer than a specified amount of time.

    Again, the key here is to expect the unexpected and be ready when it occurs. Individual log entries aren't necessarily indicative of a problem, but repeated entries most definitely are. I'd strongly advise all site administrators to enable this option, even on production sites. Determine what the "normal" response time should be (and then pad that number a little) and have ColdFusion log all page requests that take longer. If specific pages start appearing in the log repeatedly, you'll know where to spend your fine-tuning and performance-enhancing efforts.

    Up for another challenge? Write a scheduled event that checks this log file daily for new entries. If it finds any, it should e-mail them to you so you'll know about them immediately.

    When Bad Things Happen
    You've cleaned up your site. You no longer expect specific program flow, nor do you expect specific usage patterns. That's great, but it's not enough.

    The other big trouble spot is reliance on other systems and technologies. Whether it's database integration, execution of third-party objects and components, or interaction with other Internet protocols (like HTTP, FTP and NNTP), the more you rely on other systems and technologies, the more room there is for something to go wrong.

    Whether it's database failure, the inability to connect to a specific host, or errors and problems in calls resources, they're all your problem because to the end user your site is broken. It's not an ideal world out there; bad things do happen and you'll be blamed. And you're not going to escape this one anytime soon.

    So what do you do? Again, ColdFusion (version 4 or later) provides a tool to respond to these situations - try catch error handling. While full coverage of try catch is beyond the scope of this column (I'll devote an entire column to error handling in the future), here's the basic idea.

    Try catch error handling allows you to trap errors in your code, then pick up the processing elsewhere when an error occurs. The basic page layout looks like this:

    <CFTRY>
    ... page goes here ...
    <CFCATCH>
    ... error processing goes here ...
    </CFCATCH>
    </CFTRY>

    By wrapping an entire page between <CFTRY> and </CFTRY> tags, any error that occurs within that page will be trapped. As soon as an error is caught, processing will be taken over by the catch block (the code between <CFCATCH> and </CFCATCH>). There's no limit to what you can place in the catch block-you can change variables, redirect requests, generate e-mail, write logs and even try to fix error conditions.

    Experienced developers take this one step further by nesting try catch error handling. Generic error handling is implemented at the page level, and additional error handling is implemented around specific features or functions. This type of implementation provides the greatest level of control and allows developers to not just expect the unexpected, but also to handle the unexpected.

    Conclusion
    The Internet is a highly dynamic and configurable environment. With all that flexibility and power comes the need for greater caution and planning to ensure that applications don't suddenly break. Bugfree code is a wonderful ideal, but for most of us, writing good code that doesn't break in unexpected scenarios is as close as we'll get to attaining it.

    The bottom line is that as developers writing code for this new environment, we must all expect the unexpected- because it's going to happen and usually at the least opportune time.

    About Ben Forta
    Ben Forta is Adobe's evangelist for the ColdFusion product line. He is the author of several books.

  • YOUR FEEDBACK
    David Kinkead wrote: Good info, but I believe you are completely correct about textual data not being a threat. Let's say you coded in a file named test.cfm: SELECT * FROM sometable where field1 = '#preservesinglequotes(url.name)#' Then a user put in this url: http://yoursite.com/test.cfm?name=ttt';insert into sometable(field1,field2)values('xxx',99998);select * from sometable where field1='x The result is sql injection. I have tested this and know it to be true. However this will only work if you use "Preservesinglequotes", which I have used many times. So we must protect ourselves even with textual data.
    Luis Melo wrote: Our system was not SQL Injection proof and we recently suffered an attack that corrupted the data in some of our database tables. The attack was quite elegant and fortunately did not cause severe damage other than the appending of a SCRIPT sting to a bunch of VARCHAR fields. This was meant to actually execute a JS file and this qualifies as a XSS attack. In researching the Web for a solution for the problem, and a way to immunize our CF application against further attacks, we came across the CFQUERYPARAM solution, but our application has over 5000 files, each with one or more Queries and Stored Procedure calls. Implementing such a solution in such an extensive amount of files was impossible in a timely fashion, so I looked for another solution and came across a ColdFusion written function (isSqlInjection) that showed some promise but some shortcomings as well. I wanted something th...
    Angela wrote: Isn't WHERE id = #Val(url.id)# just as effective as using cfparam or cfqueryparam?
    Will wrote: Hi, I really enjoyed your article about injection attachs, but you forgot one small detial. Even if you use cfparam, it appears that you are still vuneralbe to injection attachs via forms. someone could fill a form filed with some thing like this "# #drop table" the first and last quotes seperate your statement from and move it ouside of the forms "quoes" and thene the the next two #'s creat and execute a new statement.
    CFDJ News Desk wrote: Ben Forta's ColdFusion Blog: SQL Injection Attacks, Easy To Prevent, But Apparently Still Ignored. I was just on a web site (no, not a ColdFusion powered site, and no I will not name names) browsing for specific content. The URLs used typical name=value query string conventions, and so I changed the value to jump to the page I wanted. And I made a typo and added a character to the numeric value. The result? An invalid SQL error message.
    CFDJ LATEST STORIES . . .
    SQL Injection attacks are one of the easiest ways to hack into a website. One recent hack, using a script from verynx.cn, involves injecting sql into a web form that then appends some JavaScript code into fields in a database that then gets executed on the client side when a user views...
    Mike Neil is general manager for virtualization strategy in the Windows Server Division at Microsoft. Mike is focused on the delivery of the Windows virtualization technology, including Windows Server 2008 Hyper-V, Microsoft Hyper-V Server and Virtual PC 2007. Mike also directs the tec...
    Two of the biggest launches in Rich Internet Application history took place in 2007/2008 when Adobe launched AIR 1.0 in February '08 and Microsoft launched Silverlight (September '07). At the 6th International AJAXWorld RIA Conference & Expo in October SYS-CON Events is delighted to be...
    Recursion Software released a private beta version of their Voyager mobile platform, with powerful interoperability for Android, Microsoft .NET and Compact Framework (CF), all Java editions (JME CDC, JSE and JEE), and more than 15 embedded operating systems. The Voyager platform is a p...
    2008 is going to be an important year for Rich Internet Applications. Most organizations are delivering or planning to deliver Rich Internet Applications; however, at the same time, most IT managers are facing a dilemma: which Rich Internet Application technology and platform to use? T...
    CFDynamics, a ColdFusion web host, has renewed an agreement with SmarterTools that will allow them to pass on immediate value to their customers. When a customers signs up for a dedicated hosting account they will now receive $750 worth of features including SmarterMail, SmarterStats a...
    SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
    SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


    SYS-CON FEATURED WHITEPAPERS

    ADS BY GOOGLE