3

Which EncodeFor should be used location()?

If I want to push some data via location, what should it look like?

location("obtainBDK.cfm?message=#ErrorMessage#", false); // nothing

OR

location("obtainBDK.cfm?message=#EncodeForHTMLAttribute(ErrorMessage)#", false);

OR

location("obtainBDK.cfm?message=#EncodeForURL(ErrorMessage)#", false);

OR

Something else?

James A Mohler
  • 11,060
  • 15
  • 46
  • 72

1 Answers1

4

cflocation/location sets the Location HTTP header. The browser reads this value and requests the mentioned resource via HTTP GET. Said URI should be encoded.

Now the only URI part that requires encoding is the query string, which starts with a question mark ?. Each key-value-pair consist of the encoded key, an equal-sign = and the encoded value. Multiple pairs are delimited by an ampersand &.

According to RFC 1738:

Thus, only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL.

Reserved Characters Example

Unencoded URI:
http://example.org/path?&=&&===&?

Expected key-value-pairs:

- "&": "&"
- "=": "="
- "?": ""

However, a proper parser would only see empty keys and values. We need to encode keys and values so they are not treated for their technical purpose.

Encoded URI: http://example.org/path?%26=%26&%3D=%3D&%3F&%20=%20!

Now all characters in key and value are percent-encoded according to RFC 3986 and cannot be mistaken by the parser.

ColdFusion:

kvps = [];

key = "message";
val = ErrorMessage;
kvps.append(
    urlEncodedFormat(key) & "=" & urlEncodedFormat(val)
);

targetUrl = "btainBDK.cfm?" & arrayToList(kvps, "&");
location(targetUrl, false);

urlEncodedFormat vs. encodeForUrl

Although...

Adobe recommends that you use the EncodeForURL function, not the URLEncodedFormat function, to escape special characters in a string for use in a URL in all new applications.

I encountered issues where + could not be properly distinguished between being a space or an actual plus sign, especially when the context changes (CF <-> JS). So I would recommend urlEncodedFormat regardless of Adobe's opinion about it.

Community
  • 1
  • 1
Alex
  • 7,743
  • 1
  • 18
  • 38