asp.net and cookies special characters - asp.net

Have found very interesting issue in asp.net with cookies:
when adding cookie with value like test&
using
HttpCookie cookie = new HttpCookie("test", "test&");
Response.Cookies.Add(cookie);
and then trying to retrieve value Request.Cookies["test"] trailing ampersand is lost. If it is not trailing it is not lost. In firebug or javascript data is correct so it is asp.net specific I think.
Of course mostly could say just use UrlEncode. But is it really necessary? Is there any list of disallowed charters for cookies (because I think it is smaller than for URLs)?
I have found similar topic but there is no & symbol in restricted list:
Allowed characters in cookies

The ampersand is not an allowed character in a cookie. It's necessary to encode the cookie data with the UrlEncode method.
System.Web.HttpUtility.UrlEncode(cookie);
See also these SO questions/answers:
Broken string in cookie after ampersand (javascript)
How do you use an Ampersand in an HTTPCookie in VB.NET?

Related

Cookie encoding in BASE64 cannot be sent correctly to server

I use BASE64 to encode GUID value and add them to cookie. For example, an ecoded guid value is vClFwpDbWE6JPUlnlBXMWg==. When the server sends response, it will add this cookie. I check with Chrome, this value is correctly received by the browser. But when the browser sends another request, the cookie value is changed to "vClFwpDbWE6JPUlnlBXMWg" from HttpRequestMessage's cookies, why some characters are removed?
I use WebAPI2, MVC5 with IIS7.5.
ASP.NET sees the '=' character in the cookie and assumes it's a multi-value cookie (see related question Storing multiple values in cookies).
Your best bet is to store the GUID in the cookie as-is, e.g., by using Guid.ToString() to turn the GUID into a hex string and new Guid(string) to turn the hex string back into a GUID. Alternatively, if you really need to condense it down to BASE64, consider using HttpServerUtility's UrlTokenEncode and UrlTokenDecode methods. Those methods use an encoding which is very similar to BASE64 but which doesn't use characters like '+' and '=' which are treated specially by ASP.NET.

How to create cookie without quotes around value?

I need to create cookie with e-mail address as value - but when I try to - then I have result:
"someone#example.com"
but I would like to have:
someone#example.com
The cookie should be created without double quoted marks - because other application uses it in such format. How to force java to not to add double quoted? Java adds them because there is special char "at".
I create the cookie that way:
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
Cookie cookie = new Cookie("login", "someone#example.com");
cookie.setMaxAge(2592000);
cookie.setDomain("domain.com");
cookie.setVersion(1);
response.addCookie(cookie);
Thanks for any help.
It's indeed caused by the # sign. This is not allowed in version 0 cookies. The container will implicitly force it to become a version 1 cookie (which breaks in MSIE browsers). You'd like to URL-encode the cookie value on cookie's creation
Cookie cookie = new Cookie("login", URLEncoder.encode("someone#example.com", "UTF-8"));
cookie.setMaxAge(2592000);
cookie.setDomain("domain.com");
response.addCookie(cookie);
and URL-decode it on cookie reading
String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
Note that you should for sure not explicitly set the cookie version to 1.
See also:
Why do cookie values with whitespace arrive at the client side with quotes?
Unrelated to the concrete problem, cookies are visible and manipulatable by the enduser or man-in-the-middle. Carrying the email address around in a cookie is a bad smell. What if the enduser changes it to a different address? Whatever functional requirement (remembering the login?) you thought to solve with carrying the email address around in a cookie should most likely be solved differently.
See also:
How do I keep a user logged into my site for months?

Issue storing ampersand in cookie

On my site i have used cookie to store few details in browser.
The issue is, it doesn't store value which ends with ampersand. i.e. HiAll655& loads back as HiAll655
I found that cookie creates issue with few characters like ampersand but it stores & loads value like HiAll655&HiAll properly.
Any help would be appreciated.
Thank you
You can use HttpUtility.UrlEncode(string) when storing the value, and HttpUtility.UrlDecode(string) when reading the value.
UrlEncode transforms & to %26 which is safe to use in cookies.

Request() vs Request.QueryString()

I have recently started using Request("key") instead of Request.QueryString("key") to access my querystring values. However I have read that:
Gets the specified object from the System.Web.HttpRequest.Cookies,
System.Web.HttpRequest.Form, System.Web.HttpRequest.QueryString,
System.Web.HttpRequest.ServerVariables
Therefore, if I have a querystring key and cookie key which are the same, which value is returned?
They're checked in the following order:
QueryString
Form
Cookies
ServerVariables
The search is short-circuited, so as soon as a matching key is found the value is returned.
So, to answer your question, a matching QueryString item takes precedence over Cookies.

Why do cookie values with whitespace arrive at the client side with quotes?

I'm a .NET developer starting to dabble in Java.
In .NET, I can set the value of a cookie to a string with white space in it:
new HttpCookie("myCookieName", "my value") - and when I read that value on the client side (JavaScript), I get the value I expected (my value).
If I do the same thing in a Java servlet - new Cookie("myCookieName", "my value"), I get the value including the double quotes ("my value").
Why the difference? Am I missing something? How do people handle this in the Java world? Do you encode the value and then you decode on the client side?
When you set a cookie value with one of the following values as mentioned in Cookie#setValue(),
With Version 0 cookies, values should not contain white space, brackets, parentheses, equals signs, commas, double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same way on all browsers.
then the average container will implicitly set the cookie to version 1 (RFC 2109 spec) instead of the default version 0 (Netscape spec). The behaviour is not specified by the Servlet API, the container is free to implement it (it may for example throw some IllegalArgumentException). As far as I know, Tomcat, JBoss AS and Glassfish behave all the same with regard to implicitly changing the cookie version. For at least Tomcat and JBoss AS this is the consequence of fixes for this security issue.
A version 1 cookie look like this:
name="value with spaces";Max-Age=3600;Path=/;Version=1
while a version 0 compatible cookie look like this:
name=value%20with%20spaces;Expires=Mon, 29-Aug-2011 14:30:00 GMT;Path=/
(note that an URL-encoded value is valid for version 0)
Important note is that Microsoft Internet Explorer doesn't support version 1 cookies. Even not the current IE 11 release. It'll interpret the quotes being part of the whole cookie value and will treat and return that accordingly. It does not support the Max-Age attribute and it'll ignore it altogether which causes that the cookie's lifetime defaults to the browser session. You was apparently using IE to test the cookie handling of your webapp.
To support MSIE as well, you really need to URL-encode and URL-decode the cookie value yourself if it contains possibly characters which are invalid for version 0.
Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
// ...
and
String value = URLDecoder.decode(cookie.getValue(), "UTF-8"));
// ...
In order to support version 1 cookies for the worldwide audience, you'll really wait for Microsoft to fix the lack of MSIE support and that the browser with the fix has become mainstream. In other words, it'll take ages (update: as of now, 5+ years later, it doesn't seem to ever going to happen). In the meanwhile you'd best stick to version 0 compatible cookies.
As far as I know, spaces must be encoded in cookies. Different browsers react differently to un-encoded cookies. You should URL-encode your cookie before setting it.
String cookieval = "my value";
String cookieenc = URLEncoder.encode(cookieval, "UTF-8");
res.addCookie(new Cookie("myCookieName", cookieenc));
ASP.NET does the encoding automatically, in Java you have to do it yourself. I suspect the quotes you see are added by the user agent.
It probably has to do with the way Java encodes the cookie. I suggest you try calling setVersion(1) on the new cookie and see if that works for you.
Try using setVersion(0).
HttpCookie cookie = new HttpCookie("name", "multi word value");
System.out.println(cookie.toString());
prints:
name="several word value"
But after setting
cookie.setVersion(0);
System.out.println(cookie.toString());
prints:
name=several word value
Encoding is a good idea too, but the quotes around the value look to be an independent issue.

Resources