CFMX 7: Little Notes on New Features
by Pete Freitag
The following content originally appeared in Pete Freitag's blog, http://www.petefreitag.com/, and we've recompiled it (and edited it) with Pete's permission:
CFPARAM Tag
If you're like me, you use a CFPARAM tag to validate and initialize all of your form and/or URL variables. Using something like the following code can help prevent SQL injection attacks (though CFQUERYPARAM is more exact for this):
|
<CFPARAM name="url.id" default="0" type="numeric">
|
However, in most cases your id is stored as an integer in your database, and integers allow for decimal places. If these are passed, they may cause your database to throw an exception.
ColdFusion MX 7.0 introduces the following new validation types:
- creditcard - After stripping blanks and dashes, a number that conforms to the mod10 algorithm. Number must have 13-16 digits.
- email - Valid address characters include a-z, A-Z and 0-9_, and the period and separator. There must be a single at sign (@) and the text after the @ character must include a period.
- eurodate - A date in the form d/m/y, d-m-y, or d.m.y. The m and d format can be one or two digits; y can be two or four digits. Converts the input to ODBC date format. Allows entry of a time part, but removes it from the ODBC value.
- float - same as numeric
- integer - An integer of the range -2,147,483,648 -- 2,147,483,647
- range - a numeric value between the values specified in the min and max attribute.
- regex - value must match the regular expression passed into the pattern attribute.
- regular_expression - same as regex
- ssn - A nine-digit Social Security number. Can be of the form xxx-xx-xxxx or xxx xx xxxx.
- social_security_number - same as ssn
- time - A time. It can be in 12-hour or 24-hour clock format, and can include seconds in the form hh:mm:ss or a case-independent am or pm indicator. Converts the input to ODBC time format. Allows entry of a date part, but removes it from the ODBC value.
- url - A valid URL. Must start with http:\\, https:\\, ftp:\\, file:\\, mailto:, or news:. Can include, as appropriate, username and password designators and query strings. The main part of the address can only have the characters A-Za-z0-9 and -.
- usdate - A date in the form m/d/y, m-d-y , or m.d.y, The m and d format can be 1 or 2 digits; y can be 2 or 4 digits. Does not convert the string to an ODBC value and does not allow a time part.
- zipcode - A 5-digit or 9-digit U.S. ZIP code. In 9-digit codes, the final four digits must be preceded by a hyphen (-) or space.
Some of the type descriptions above are from the
Macromedia Livedocs.
So with these new validation types we can simply use the following to validate that our id is an integer:
|
<CFPARAM name="url.id" default="0" type="integer">
|
If we want to validate an email address format we can use:
|
<CFPARAM name="url.email" type="email">
|
Side Note: For more complete email verification, you might want to check out Email Verifier from
CFDEV.
But for me, the coolest type is the regex type. So if I want to validate that a string is all lowercase letters (a-z), and contains at least one letter, I would use:
|
<CFPARAM name="url.string" type="regex" pattern="[a-z]+">
|
Another cool type is the range type, as you can pass in a min and/or max value:
|
<CFPARAM name="url.age" type="range" min="21" max="100">
|
There is one limitation of the range feature: It operates on numerical values, and that allows for decimal places as well as whole numbers. Let's suppose you don't want people passing in that they are 24.5 years old. You can do something like this:
|
<CFPARAM name="url.age" type="integer">
<CFPARAM name="url.age" type="range" min="21" max="100">
|
In the code above, I first check and see that the age is an integer, and if it is, I check the range. While this works, it would have been nice if min and max worked with the integer type as well. I didn't notice this during the beta. Perhaps someone else did, and there is a valid reason for this limitation?
IsValid Function
ColdFusion MX 7 added a new function called IsValid. The IsValid function performs data validation just like the CFPARAM tag, and supports all the new data types in CFPARAM (see my previous post) as well.
For instance, if we want to validate that a variable has an integer value:
|
<CFIF IsValid("integer", url.value)>
Valid integer!
<CFELSE>
Invalid Integer!
</CFIF>
|
For a range:
|
<CFIF IsValid("range", url.value, 1, 100)>
Value is between 1 and 100
<CFELSE>
Value is not between 1 and 100
</CFIF>
|
And for Regular Expressions:
|
<CFIF IsValid("regex", url.value, "[A-Z][a-z]+")>
Word starts with a capital letter
<CFELSE>
Word does not match pattern.
</CFIF>
|
CFTIMER Tag
I am digging the new CFTIMER tag in ColdFusion MX 7.
In previous versions, when you wanted to time how long something takes, you would do something like this:
|
<CFSET tick = GetTickCount()>
run your code here...
<CFSET tock = GetTickCount()>
<CFSET time = tock-tick>
<CFOUTPUT>it took #time#ms</CFOUTPUT>
|
In ColdFusion MX 7, you just need to wrap your code with the CFTIMER tag (and turn on the "Display Timer Information" option in the ColdFusion Administrator)
|
<CFTIMER label="Google Download Timer" type="outline">
<CFHTTP method="get" url="http://www.google.com/">
</CFHTTP>
<CFOUTPUT>downloaded google</cfoutput>
</CFTIMER>
|
And it will output something like this:
Google Download Timer: 62ms downloaded google
There are four output types you can use:
- type="inline": Just displays the timer at the position of the </CFTIMER> tag
- type="comment": This will insert the timer into an HTML comment, e.g.: <!--Google Download Timer: 62 ms -->
- type="debug": This displays the timers at the bottom of the page with the debug output.
- type="outline": This outlines the code being timed. Note that your browser must support the fieldset and legend tags for the above code to show up properly with CFTIMER type="outline".
CFDIRECTORY Adds Recursive Support
I know I have written recursive custom tags and functions (more than once) to solve this problem in the past, but now you can just add a simple recurse="true" to your CFDIRECTORY tags in ColdFusion MX 7.
|
<CFDIRECTORY action="list"
directory="#ExpandPath("./")#" name="dir"
recurse="true">
<CFDUMP var="#dir#">
|
You can also recursively delete directories. If only you could copy directories recursively. (Hint, hint ... ColdFusion 8?)
Strong Encryption
ColdFusion MX 7 adds strong encryption support to the Encrypt and Decrypt functions. In addition to the legacy algorithm used in Encrypt and Decrypt, ColdFusion MX 7 now makes it incredibly easy to use AES, Blowfish, DES, and Triple DES encryption. It also adds the ability to encode the encrypted string using three different binary encoding algorithms -- Base64, Hexidecimal, and the UUEncode algorithm.
Here's an example:
|
<!--- options for algorithm are
CFMX_COMPAT (default), AES, BLOWFISH, DES, and DESEDE --->
<CFSET algorithm = "AES">
<!--- encoding options, Base64, hex, or uu --->
<CFSET encoding = "hex">
<!--- generate a key --->
<CFSET key = GenerateSecretKey(algorithm)>
<CFSET str = "This is my secret string." >
<CFSET enc = Encrypt(str, key, algorithm, encoding)>
<CFSET dec = Decrypt(enc, key, algorithm, encoding)>
<CFOUTPUT>
<PRE>
string=#str#
encrypted=#enc#
decrypted=#dec#
key=#key#
algorithm=#algorithm#
</pre>
</CFOUTPUT>
|
Encoding
The default encoding algorithm is UUEncode. This algorithm, however, may not be best if you need to pass the encrypted value around (as the possible character values are greatest). The safest choice for encoding is hex, which will only use the characters A-F and 0-9 - it also will yield the longest string. The next best choice is Base64 encoding, which uses characters in the a-z, A-Z and 0-9 ranges, and sometimes will use = signs at the end for padding.
Encryption Algorithms
The DES (Data Encryption Standard) algorithm was developed in the United States in the 1970's by the NSA. DES is no longer considered secure and can be broken in hours or days by exhaustive key search. There are around 72 quadrillion possible keys.
Triple DES (DESEDE): To make it harder to break we encrypt using one key, encrypt using another key, and finally decrypt using the first key. Triple DES is still considered a secure algorithm, and is in wide use.
The AES/Rijndael (Advanced Encryption Standard) algorithm is your strongest choice. It uses at least 128 bit keys (it can use 128, 192 or 256), and it executes even faster than DES and Triple DES algorithms (which use 56 bit keys).
"Assuming that one could build a machine that could recover a DES key in a second (i.e., try 255 keys per second), then it would take that machine approximately 149 thousand-billion (149 trillion) years to crack a 128-bit AES key.? --
NIST AES Fact Sheet
The blowfish algorithm was also designed as a replacement to DES - it uses variable key lengths (32-448 bits) and is appropriate for both domestic (US) and international use. Blowfish is significantly faster than DES (20x).
| Algorithm |
Strength |
Speed |
Key Length |
| DES |
Low |
Slow |
256 |
| Triple DES |
Good |
Slowest |
256 |
| Blowfish |
Strong |
Fast, but time consuming to initialize a new key |
232 - 2448 |
| AES |
Strong |
Fast |
2128, 2192, 2256 |
Other Sources:
An Introduction to Modern Crypto Systems,
Do We Need AES? and
Description of a new variable-length key, 64-bit block cipher (blowfish) -- all good reads.
ColdFusion MX 7 is packed with lots of these little new features, that are, well killer! I hope that this article helped to expose some of these useful new features and subtle improvements. In the end, these small subtleties will help you write better ColdFusion code in CFMX 7.