Seybsen
Seybsen

Reputation: 15587

ColdFusion: #URLSessionFormat("index.cfm?foo=bar")# -> two questionmarks in URL when cookies disabled

My form looks something like this:

 <form name="foo_contact" action="<CFOUTPUT>#URLSessionFormat("index.cfm?foo=bar")#</CFOUTPUT>">

When I disable cookies and submit the form my URL looks like this: index.cfm?foo=bar?CFID=12345&CFTOKEN=12312312 which is not what I expected. It should read index.cfm?foo=bar&CFID=12345&CFTOKEN=12312312

Am I doing something wrong here? Do I need to write a function by myself to fix it or is there an easy solution I missed?

Upvotes: 1

Views: 670

Answers (3)

Miguel-F
Miguel-F

Reputation: 13548

You need to be aware of the potential security issues when using CFID and CFTOKEN. These issues can be remedied by simply using J2EE session management instead. Here is an excerpt from the ColdFusion documentation here:

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:

3ee6c307a7278c7b-5278BEA6-1030-C351-3E33390F2EAD02B9

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.

Security-related changes

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 httpOnly depends 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.

Upvotes: 0

Peter Boughton
Peter Boughton

Reputation: 112220

Simple option - use a hidden form var instead.

<form name="foo_contact" action="<CFOUTPUT>#URLSessionFormat("index.cfm")#</CFOUTPUT>">
    <input type="hidden" name="foo" value="bar" />


Alternative option - change the relevant ? to a & afterwards:

<cfset ActionUrl = URLSessionFormat("index.cfm?foo=bar")
    .replaceFirst('(?<!^index\.cfm)\?','&') />

<form name="foo_contact" action="<cfoutput>#ActionUrl#</cfoutput>">

This .replaceFirst uses a regex with negative lookbehind (the (?<!..) part) to find the first ? that is not preceeded by index.cfm and replaces it.

Upvotes: 2

Dan Short
Dan Short

Reputation: 9616

You should write it like so:

#URLSessionFormat("index.cfm")#&foo=bar

Upvotes: 0

Related Questions