Because the web is a stateless system, each connection that a browser makes to a web server is unique to the web server. However, many applications must keep track of users as they move through the pages within the application. This is the definition of client state management.
ColdFusion provides tools to maintain the client state by seamlessly tracking variables associated with a browser as the user moves from page to page within the application. You can use these variables in place of other methods for tracking client state, such as URL parameters, hidden form fields, and HTTP cookies.
About client and session variables
ColdFusion provides two tools for managing the client state: client variables and session variables. Both types of variables are associated with a specific client, but you manage and use them differently, as described in the following table:
Data is saved as cookies, database entries, or Registry entries. Data is saved between server restarts, but is initially accessed and saved more slowly than data stored in memory.Each type of data storage has its own time-out period. You can specify the database and Registry data time-outs in the ColdFusion Administrator. ColdFusion sets Cookie client variables to expire after approximately ten years.Data is stored on a per-user and per-application basis. For example, if you store client variables as cookies, the user has a separate cookie for each ColdFusion application provided by a server.Client variables must be simple variables, such as numbers, dates, or strings. They cannot be arrays, structures, query objects, or other objects.Client variable names can include periods. For example, My.ClientVar is a valid name for a simple client variable. Avoid such names, however, to ensure code clarity.You do not have to prefix client variables with the scope name when you reference them, However, if you do not use the Client prefix, you might unintentionally refer to a variable with the same name in another scope. Using the prefix also optimizes performance and increases program clarity.You do not lock code that uses client variables.You can use client variables that are stored in cookies or a common database in clustered systems.
Data is stored in memory so it is accessed quickly.Data is lost when the client browser is inactive for a time-out period. You specify the time-out in the ColdFusion Administrator, the Application.cfc initialization code, or Application.cfm.As with client variables, data is available to a single client and application only.Variables can store any ColdFusion data type.You must prefix all variable names with the Session scope name.Lock code that uses session variables to prevent race conditions.You can use session variables in clustered systems only if the systems support "sticky" sessions, where a session is limited to a single server.
Session variables are normally better than client variables for values that need to exist for only a single browser session. Reserve client variables for client-specific data, such as client preferences that you want available for multiple browser sessions.
Maintaining client identity
Because the web is a stateless system, client management requires some method for maintaining knowledge of the client between requests. Normally you do this using cookies, but you can also do it by passing information between application pages. Information about how ColdFusion maintains client identity in a variety of configurations and environments, and the issues that can arise with client state management are described as follows:
About client identifiers
To use client and session variables, ColdFusion must be able to identify the client. It normally does so by setting the following two cookie values on the client's system:
- CFID: A sequential client identifier
- CFToken: A random-number client security token
These cookies uniquely identify the client to ColdFusion, which also maintains copies of the variables as part of the Session and Client scopes. You can configure your application so that it does not use client cookies, but in this case, pass these variables to all the pages that your application calls. For more information about maintaining client and session information without using cookies, see Using client and session variables without cookies section below.
You can configure ColdFusion to use J2EE servlet session management instead of ColdFusion session management for session variables. This method of session management does not use CFID and CFToken values, but does use a client-side jsessionid session management cookie. For more information on using J2EE session management, see ColdFusion and J2EE session management in Configuring and using session variables.
Using client and session variables without cookies
Often, users disable cookies in their browsers. In this case, ColdFusion cannot maintain the client state automatically. You can use client or session variables without using cookies, by passing the client identification information between application pages. However, this technique has significant limitations, as follows:
- Client variables are effectively the same as session variables, except that they leave unusable data in the client data store.Because the client's system does not retain any identification information, the next time the user logs on, ColdFusion cannot identify the user with the previous client and must create a new client ID for the user. Any information about the user from a previous session is not available, but remains in client data storage until ColdFusion deletes it. If you clear the Purge Data for Clients that Remain Unvisited option in the ColdFusion Administrator, ColdFusion never deletes this data.Therefore, do not use client variables, if you allow users to disable cookies. To retain client information without cookies, require users to login with a unique ID. You can then save user-specific information in a database with the user's ID as a key.
- ColdFusion creates a new session each time the user requests a page directly in the browser, because the new request contains no state information to indicate the session or client.
Note: You can prevent ColdFusion from sending client information to the browser as cookies by setting This.setClientCookies variable in Application.cfc or the setClientCookies attribute of the cfapplication tag to No.
To use ColdFusion session variables without using cookies, each page must pass the CFID and CFToken values to any page that it calls as part of the request URL. If a page contains any HTML href a= links, cflocation tags, form tags, or cfform tags the tags must pass the CFID and CFToken values in the tag URL. To use J2EE session management, pass the jsessionid value in page requests. To use ColdFusion client variables and J2EE session variables, pass the CFID, CFToken, and jsessionid values in URLs.
Note: The behavior is as follows when CFID and CFTOKEN are provided in the URL: If session exists, the CFID and CFTOKEN from the URL are ignored. If the session does not exist, CFID and CFTOKEN from the URL are used to validate the session and the session is used if it is valid. If the session is not valid, a new session is created. CFID and CFTOKEN are regenerated.
ColdFusion provides the URLSessionFormat function, which does the following:
- If the client does not accept cookies, automatically appends all required client identification information to a URL.
- If the client accepts cookies, does not append the information.
The URLSessionFormat function automatically determines which identifiers are required, and sends only the required information. It also provides a more secure and robust method for supporting client identification than manually encoding the information in each URL, because it only sends the information that is required, when it is required, and it is easier to code.
To use the URLSessionFormat function, enclose the request URL in the function. For example, the following cfform tag posts a request to another page and sends the client identification, if necessary:
<cfform method="Post" action="#URLSessionFormat("MyActionPage.cfm")#>
Note: If you use the same page URL in multiple URLSessionFormat_ functions, you can gain a small performance improvement and simplify your code if you assign the formatted page URL to a variable, for example:_
Client identifiers and security
The following client identifier issues can have security implications:
- Ensuring the uniqueness and complexity of the CFToken identifier
- Limiting the availability of Session identifiers
The next sections discuss these issues.
Ensuring CFToken uniqueness and security
By default, ColdFusion uses an eight-digit random number in the CFToken identifier. This CFToken format provides a unique, secure identifier for users under most circumstances. (In ColdFusion, the method for generating this number uses a cryptographic-strength random number generator that is seeded only when the server starts.)
However, in the ColdFusion Administrator, you can enable the Settings page to produce a more complex CFToken identifier. If you enable the Use UUID for cftoken option, ColdFusion creates the CFToken value by prepending a 16-digit random hexadecimal number to a ColdFusion UUID. The resulting CFToken identifier looks similar to the following:
Providing Session security
ColdFusion uses the same client identifiers for the Client scope and the standard Session scope. Because the CFToken and CFID values are used to identify a client over a period of time, they are normally saved as cookies on the user's browser. These cookies persist until the client's browser deletes them, which can be a considerable length of time. As a result, hackers could have more access to these variables than if ColdFusion used different user identifiers for each session.
A hacker who has the user's CFToken and CFID cookies could gain access to user data by accessing a web page during the user's session using the stolen CFToken and CFID cookies. While this scenario is unlikely, it is theoretically possible.
You can remove this vulnerability by selecting the Use J2EE Session Variables option on the ColdFusion Administrator Memory Variables page. The J2EE session management mechanism creates a new session identifier for each session, and does not use either the CFToken or the CFID cookie value.
The following security-related specifications apply when you upgrade to ColdFusion 9 Upgrade 1:
- CFID, CFTOKEN, and jsessionid are marked httpOnly. This reduces the chance of session information being compromised on Cross Site Scripting (XSS) attack.
- Set the following system property for the session cookies to be httpOnly: Dcoldfusion.sessioncookie.httponly=true
- The support for session cookies to be httpOnlydepends on the application server you use:
- For Tomcat/JBoss, httpOnly is not supported for JSESSIONID
- On JRun, add the system property, Dcoldfusion.sessioncookie.httponly=true , in the jvm.config file
- For other application servers, see the relevant documentation for details on httpOnly support for session cookies.
Managing client identity information in a clustered environment
To maintain your application's client identity information in a clustered server environment, you must specify This.setdomaincookies="True" in the Application.cfc initialization code, or use the cfapplication setdomaincookies attribute in your Application.cfm page.
The setdomaincookies attribute specifies that the server-side copies of the CFID and CFToken variables used to identify the client to ColdFusion are stored at the domain level (for example, .adobe.com). If CFID and CFToken variable combinations exist on each host in the cluster, ColdFusion migrates the host-level variables on each cluster member to the single, common domain-level variable. Following the setting or migration of host-level cookie variables to domain-level variables, ColdFusion creates a new cookie variable (CFMagic) that tells ColdFusion that domain-level cookies have been set.
If you use client variables in a clustered system, you must also use a database or cookies to store the variables.