views:

910

answers:

2

Hi!

How should you encode the actual value for a Java Cookie object? I cannot pass characters like '=' or any character outside US-ASCII.

/Br joynes

+2  A: 

It does not really matter how, but usually Base64 should work well.

A cautionary note:

This sounds like you want to store arbitrary settings in a cookie. This is generally not a good idea, because cookies (like all client input) are untrusted. Consider storing the data server-side under some generated (random!) identifier, and putting that into the cookie. That way people cannot circumvent access restrictions or inject arbitrary data into your system through manipulated cookies.

If you cannot use this approach, treat cookie values as untrusted input and verify it as usual.

Edit:

Base64 is not appropriate, as it uses "=", which Java cookies do not support. Rather use

java.net.URLEncoder.encode

which only uses characters appropriate for cookies.

sleske
A cautionary note note: It's possible to encrypt the contents of cookies if you want to prevent people from manipulating them but don't want to store them on the server.
sfussenegger
Not really related to the question, but encrypting a cookie cannot prevent the client from manipulating them. Encryption will only hide from the client what the cookie actually contains. If you require that the client cannot manipulate the content of a cookie, you will have to _sign_ it and verify server-side that the content matches the signature, when a cookie is received from a client.
jarnbjo
@jambjo: Well, if the client manipulates the content of an encrypted cookie, it will decrypt to random garbage (at least with any decent encryption algorithm). So while it's true the client can technically manipulate the cookie, it's unlikely they could actually accomplish more than a DOS (still a point to consider).
sleske
(cont) If you encrypt the cookie, you don't need to sign the value. A simple checksum (encrypted along the values of the cookie) is enough. If the encrypted value is manipulated, the checksum will no longer match, and fixing it is impossible without the key.
sleske
I cant really go with the server-side identifier solution due to different reasons. I could go for encryption but I dont really need that. If Base64 is good enough I can use that as long as those characters does not break the cookie value (cannot include chars like = and ").
joynes
One problem with the Base64 solution is that it includes the '=' character. When using the class Cookie in Java it cuts the value when encountering the '=' character. Is there any better encoding?
joynes
@sleske: It is difficult to tell what the server will do with the cookie data if it is decrypted to garbage. If the cookie or a part of it can only contain a limited number of actual values, e.g. "a" and "b", a bogus client has a cookie with the value set to a and the server is implemented like "if cookie=a then ... else ...", the client may very well be able to modify the cookie and make the server to something it should not. When it comes to signing: What is the difference between an encrypted checksum and a signature?
jarnbjo
@jarnbjo: You are right, relying on modified cookies coming out as garbage is dangerous.
sleske
As to the difference between an encrypted checksum and a signature: A signature is usually implemented using public key cryptography, while an encrypted checksum could use symmetric cryptography. But it really boils down to a matter of definition...
sleske
+1  A: 

Use hex or URL-safe version of Base64 to encode it if you have unsafe chars. Regular Base64 can't be used as cookie values. Older Tomcat used to allow illegal chars in it like "=" but newer versions start to enforce the cookie rules now.

ZZ Coder