• No results found

The <CFPARAM> tag is the closest ColdFusion gets to instantiating a variable prior to use. <CFPARAM> allows developers to assign default values and data

types to variables, ensuring that they exist, are of the right data type, and have a value.This type of functionality comes in very handy when dealing with Form- and URL-scoped variables in particular. Developers have to be careful to not let the <CFPARAM> tag become a crutch (which happens to the best of us).The

<CFPARAM> tag can assign default values for variables of any scope: URL, Form,

Application, Session, etc. Having a default to work with allows developers to test for errors and missing variables. Defaulting a variable to “0” and changing that value at some point in the application provides a good method of error checking. If the variable still equals “0” when it is used next, then there is a problem. Figure 2.10 provides sample code that uses <CFPARAM> to instantiate a variable and then test whether the variable has changed.

W

ARNING

A common pitfall to developers new and old is to place pound signs (#) inside the IsDefined() function. Typically, in ColdFusion when double quotes are involved, the pound signs are needed to evaluate the variable.

However, IsDefined() is not looking for a value—it checks to see if the vari- able itself is defined, having no regard for the value of the variable. The pitfall occurs because using the pound signs does not throw an error.

IsDefined() simply looks for a variable named, whatever the value is. For

example, IsDefined(“VARIABLES.FormStart”) looks for a variable named

FormStart, while IsDefined(“#VARIABLES.FormStart#”) looks for a variable

named whatever FormStart has for a value, and in most cases returns false.

Figure 2.10<CFPARAM> Indicating Program Status

<CFPARAM Name="FORM.FormComplete" Default="0">

<CFIF IsDefined("FORM.FormComplete") AND FORM.FormComplete NEQ 0>

Perform the code associated the proper completion of a form on the previous web page.

<CFELSE>

Perform code that re-directs the users' browser to the form alerting them to where they incorrectly filled in data. </CFIF>

Summary

This chapter focused on several key elements of writing more secure code, from the aspect of surviving an attack as well as bad coding.Tracking user sessions is an important part of most Web sites, and essential in any e-commerce Web site. While being able to track sessions is important, doing so securely is paramount. Web sites should never store anything more than a user ID of some sort in a ses- sion variable, just in case some hacker out there decides to take a peek at the user’s cookies.

Making use of ColdFusion’s built-in client management is a great way to move away from the more problematic session variables; however, some work must be done on the developers’ side in order to be completely free of cookies. In order to be useful, CFID and CFTOKEN must exist on a user’s computer, bringing you right back in the middle of the cookie problem. Have no fear, a solution exists to enable a Web site to use the CFID/CFTOKEN client variables and not depend on cookies: passing them as URL-scoped variables allows a Web site to assign them to a user, and track them via the URL string, rather than looking for a pair of cookies.This solution is a little more time consuming to implement, but is worth the expense if the developer wants to support the widest possible user base.

Spiders are a fairly new concept in Web development; the earliest search engines were nothing more than indexes, and the only thing in them were the Web sites that submitted themselves. As more and more search engines appeared, the need to proactively index Web sites became more pressing (after all, those who returned the most useful search results got the hits). Spiders were born. Originally, spiders did much the same thing they do today, except that they were a little simpler. Originally, a developer not wanting her site indexed simply had to place a text file called “robots.txt” in the Web site’s root folder. For better or worse, spiders have evolved and increased in number, and many do not even react to the robots.txt file anymore, making them much more of a nuisance to devel- opers. Spiders used to identify themselves with user_agents that had “spider” or “crawler” in the name, but now some pass themselves off as browsers, or worse, have blank user_agent variables. Handling spiders is more difficult now, but still manageable, with a bit of work.

Handling errors in whatever form they take (hackers, hardware or software failures, random “hiccups,” etc.) is a very important function of a Web site. Being able to identify and handle a case in which a user clicks a Submit button more than once, or goes back to a previous page and modifies the values in a form and

resubmits, are all “must haves” for Web sites today. ColdFusion provides a plethora of error-handling options for developers to choose from, including sitewide error templates, <CFTRY>/<CFCATCH> tags, <CFERROR> tags, and event logging.

The <CFTRY>/<CFCATCH> block is one of the best ways to catch and handle errors in the most dynamic way possible. Developers enclose code that has the potential to “break” within a <CFTRY> block with the appropriate

<CFCATCH> blocks, and are able to worry less about that code causing an

error that is displayed to the user. Combining this functionality with event log- ging (new to ColdFusion 5.0), the developer not only spares the user having to see an error message, but he or she is able to review the logs and know that an error occurred, when, and in what template.

When a particular piece of code is expecting to interact with a variable con- taining a DateTime data type and instead receives a string, bad things can happen. Not only is an error thrown unless a <CFCATCH> is waiting (as it should be), but now, there is a gap in the data collected. A Web site that sends out e-mails on users’ birthdays cannot do so if the user typed Sept. 10, 1975 instead of

09/10/1975; unless that data was parsed and converted into something useful, it is thrown out, leaving the birth date field empty.There is nothing worse than data with holes in it—a huge loss of sales can result from those holes.

Using ColdFusion’s built-in capabilities to verify specific data types, as well as its capability to evaluate variables, allows the developer to look at the variable prior to using it, thereby avoiding any “does not exist” errors. Using

<CFPARAM> to default variables to specific values eliminates one possible

error, because if the variable does not exist when the template loads, the

<CFPARAM> creates it with a default value.This is one of the most common

sources of errors when coding; typically, these errors are found prior to making a Web site public. Not having to instantiate variables before using them makes many developers lazy.This allows the code to examine a variable; if the default value is still present, something has gone wrong, but the default can be used so that an error is not thrown to the user—users like this a lot!

Solutions Fast Track

Session Tracking

; To remove cookie dependency, pass CFID and CFTOKEN in the URL string.

; Change the CFID to use a UUID, which is much more secure than the standard incremental value.

; When passing CFID and CFTOKEN in the URL string, make sure that all links and form actions have the variables; otherwise, new sessions will be started from whatever point the break occurred.

; The default setting for CFID/CFTOKEN is to use an incremental number, generated by the ColdFusion Application Server (CFAS); it is possible that the exact same number could be created by another CFAS somewhere.

Error Handling

; Use <CFTRY> blocks around any questionable code, particularly queries and calls to external resources.

; Use <CFERROR> to handle exception, request, and validation errors. ; Use the built-in missing template, and sitewide request errors.

; Make use of the new logging capabilities of the CFAS. In your code, log events to the OS Event Log, and in the Administrator, look at the new log section.

; Nest <CFTRY> blocks to create your own error code hierarchy for debugging. Handle specific types of database error with different

<CFCATCH> blocks.

Verifying Data Types

; ColdFusion variables are typeless; functions are not—keep type in mind. ; Do not use the same variable for more than one thing, especially if the

; Verifying data types prior to use is accomplished with numerous functions, including evaluate(), IsDefined(), and Val().

; <CFFORM> allows data to be validated against a type and even a

format prior to passing that data along.

; Use IsDefined() any time you are accessing a variable that might not have been instantiated beforehand.

; Use <CFPARAM> tags to instantiate all variables with a default value. This serves two purposes: checking for the default value allows code to determine if a particular piece of code is working correctly, and avoids Web site crashes due to ColdFusion errors when a variable does not exist. ; When using IsDefined(), do not include pound (#) signs.

Q: Do I really need to worry about a hacker spoofing the CFID/CFTOKEN pair on my Web site?

A: How seriously you take it is up to you. One thing to think about when making a decision in this area is that if someone successfully spoofed a

CFID/CFTOKEN pair and accessed your site using those values, what would

happen? Would the hacker see someone’s personal bank information? Would he be able to order products using a stored credit card? Finally, could he transfer the contents of someone’s bank account to a new account in a dif- ferent name?

Q: I have inherited a Web site that is now being placed in a server farm.There are session variables everywhere—what can I do?

A: There are several ways to handle session variables in a server farm. ClusterCats, which ships as part of ColdFusion Server Enterprise, has an option for session- aware processing.This allows servers using ClusterCats to keep track of user

Frequently Asked Questions

The following Frequently Asked Questions, answered by the authors of this book, are designed to both measure your understanding of the concepts presented in this chapter and to assist you with real-life implementation of these concepts. To have your questions about this chapter answered by the author, browse to

sessions, making sure that once a session is started it is always routed to the same server, so that session variables are valid for that user.

Q: Should I store my client variables on my ColdFusion Application Server? A: It is advisable (in my opinion) to create a separate database to store client variables. Often times, developers create the required tables in the database that supports the Web site or application (there are only two tables needed to store client variables, and the CFAS will create them when you tell it to).This works just fine, but can become a burden when user visits increase or when more applications or Web sites begin using client variables. I always create a separate database that will act as my client variable repository; that way, all activity is local to that database and my more important data is not at risk. Q: How much effort should I put into error trapping?

A: That answer is determined by your Web site.Think about it in terms of busi- ness or revenue. If your site is an e-commerce site, how likely are people to come back to your site to buy something if they get errors when making a purchase? Chances are they will abandon their session and move on to another site to make their purchase—not only have you lost a sale, but also possibly a long-term customer.

Q: What’s the point of all the validation and checking of data types?

A: Depending on with whom you speak, ColdFusion’s lack of data types is either a blessing or a bane.To some, not needing to explicitly type a variable is one less tedious task to worry about when coding, but to others, it is a time bomb waiting in the code.While ColdFusion does not care about the data type of a variable when it is instantiated, you should.When you create a variable and give it a value, no other data type should be used with that variable; otherwise, you will never know if UserID is “John,”“123,”“jtw1708,” or anything else.While you might still not know what UserID is, if you are certain that it is a string, then you can treat it as such without caring what the actual value is.

Q: When would I want to use <CFTHROW>?

A: The <CFTHROW> tag allows you to create your own errors.This is useful if you would prefer to write your own, more descriptive error messages.

Sometimes it’s beneficial to halt a routine at an early stage rather than pos- sibly risk corrupting data or causing a memory leak, or worse, on the server.

Using <CFTHROW> with <CFIF> you can check for specific conditions and act accordingly when it suits you, rather than wait for an error serious enough to halt the CFAS.Throwing your own custom errors does not mean you are halting the Web site or interfering with the user’s session on the site. The error you throw is treated just like an error thrown by the application server itself.

Q: Why not simply put an entire template within a <CFTRY> block?

A: While doing this is certainly possible, it is not advised. Placing an entire tem- plate within a <CFTRY> block means that before the user’s browser sees anything (the browser is sitting there with a white screen and a spinning logo), the CFAS must process the entire template, looking for errors that can be caught.This is a great deal of work that must be done in order to display the page. Moreover, when errors are caught, entire pages must be included in the <CFCATCH> blocks because the original code had an error and now the <CFCATCH> code needs to be processed.

Q: Couldn’t I just use <CFIF> statements to write my own error-trapping routines?

A: You could in many cases. However, if a <CFQUERY> tag generates an SQL error or a <CFINCLUDE> can not find the template it is looking for, the error condition occurs before the following <CFIF> and the processing of the template stops before anything else can happen.The <CFTRY> tag holds the error and uses the <CFCATCH> tags to examine the error. If no

<CFCATCH> tags accept the error, then the standard black-and-white

ColdFusion error is displayed.

Q: How can I monitor user visits and page hits using client variables?

A: In the ColdFusion Administrator, under the Client Variables section when cre- ating a CLIENT variable store, there are three check boxes.The first and third are checked by default; the second is not.The second check box turns on global updates for the client variables.When turned on, variables are modified with each page visit, instead of just when the actual variables are modified.

Securing Your