Opened 7 years ago

Closed 7 years ago

#16253 closed defect (invalid)

Settting a cookie with cookie() prevents alternate encoding

Reported by: danorton Owned by: danorton
Priority: undecided Milestone: tbd
Component: Core Version: 1.8.1
Keywords: Cc:
Blocked By: Blocking:

Description

The method to set a cookie, cookie(), always URL-encodes the cookie value. This prevents other encoding mechanisms and arbitrarily imposes an encoding/decoding mechanism.

There is nothing in the related specification, RFC 6265, "HTTP State Management Mechanism", that calls for any encoding. The specification only indicates the subset of ASCII characters that are allowed and, for cookies that might represent content with other characters, it leaves the encoding method up to the server and the client. The specification suggests, as an example, Base64 encoding.

With the current dojo method, values that are Base64 strings also get URL-encoded. This is evident with the equals sign ("="), a valid cookie value character under RFC 6265. Consequently, cookie values using the encoding mechanism suggested by RFC 6265 will be corrupted by the current dojo cookie() method.

The attached patch attempts to work around this issue by first checking to see if the submitted cookie value is restricted to the set of characters allowed by RFC 6265. If it is, it uses that value, unmodified. If the value contains invalid characters, it encodes the value as before, using encodeURIComponent().

In addition to changing code internal to the cookie() method, this patch adds property _reValidCookieValue, a RegExp?() that validates cookie value characters.

The patch design has a notable risk: Characters that are valid under RFC 6265 but that are normally encoded by encodeURIComponent() will pass through unencoded if the cookie value has no invalid characters. This is problematic for the percent ("%") character, possibly the equals-sign character and possibly others. One workaround is to encode the value before invoking the cookie() method.

Attachments (2)

cookie.js.patch (934 bytes) - added by danorton 7 years ago.
cookie.js.2.patch (1.0 KB) - added by danorton 7 years ago.
Provides complete backward compatibility

Download all attachments as: .zip

Change History (5)

Changed 7 years ago by danorton

Attachment: cookie.js.patch added

comment:1 Changed 7 years ago by danorton

On second thought, I like this second patch better. It removes the risk mentioned and provides a method for selecting the validation string. By default, there is no validation RegExp? and the behavior is exactly as before.

With this patch, by default, the value mentioned above, _reValidCookieValue, is null, and no validation check is made. To select validation according to the RFC, set it to _reValidCookieValueRFC6265. Any RegExp?() can be assigned.

e.g. before setting a cookie with cookie():

cookie._reValidCookieValue = cookie._reValidCookieValueRFC6265; // follow the RFC
Last edited 7 years ago by danorton (previous) (diff)

Changed 7 years ago by danorton

Attachment: cookie.js.2.patch added

Provides complete backward compatibility

comment:2 Changed 7 years ago by bill

Component: GeneralCore
Owner: set to danorton
Status: newpending

It sounds like it might be good to change for 2.0, but I'm skeptical that we need to change it now, especially with branching based on a regex.

With the current dojo method, values that are Base64 strings also get URL-encoded.

Yes, if the user pre-encoded their cookie value using Base64, then the cookie would be doubly encoded. That would be inefficient. Not sure that there's a bigger problem though.

This is evident with the equals sign ("="), a valid cookie value character under RFC 6265. Consequently, cookie values using the encoding mechanism suggested by RFC 6265 will be corrupted by the current dojo cookie() method.

I don't understand. If it's base64 encoded to begin with then there is no equals sign. How can it get corrupted? The two possibly problematic characters I see in the base 64 alphabet are + and /.

Perhaps you are saying that there's a problem with cookie("+"), because (according to your description) it gets URL encoded into %2B, which is invalid for a cookie due to the percent sign?

The specification only indicates the subset of ASCII characters that are allowed and, for cookies that might represent content with other characters, it leaves the encoding method up to the server and the client. The specification suggests, as an example, Base64 encoding.

Which characters exactly are disallowed? And, can you give an example where the code is actually failing on some supported browser, rather than just violating the spec?

comment:3 Changed 7 years ago by trac-o-bot

Resolution: invalid
Status: pendingclosed

Because we get so many tickets, we often need to return them to the initial reporter for more information. If that person does not reply within 14 days, the ticket will automatically be closed, and that has happened in this case. If you still are interested in pursuing this issue, feel free to add a comment with the requested information and we will be happy to reopen the ticket if it is still valid. Thanks!

Note: See TracTickets for help on using tickets.