views:

1608

answers:

4

I'm trying to store an xml serialized object in a cookie, but i get an error like this:

A potentially dangerous Request.Cookies value was detected from the client (KundeContextCookie="<?xml version="1.0" ...")

I know the problem from similiar cases when you try to store something that looks like javascript code in a form input field.

What is the best practise here? Is there a way (like the form problem i described) to supress this warning from the asp.net framework, or should i JSON serialize instead or perhaps should i binary serialize it? What is common practise when storing serialized data in a cookie?

EDIT: Thanks for the feedback. The reason i want to store more data in the cookie than the ID is because the object i really need takes about 2 seconds to retreive from a service i have no control over. I made a lightweight object 'KundeContext' to hold a few of the properties from the full object, but these are used 90% of the time. This way i only have to call the slow service on 10% of my pages. If i only stored the Id i would still have to call the service on almost all my pages.

I could store all the strings and ints seperately but the object has other lightweight objects like 'contactinformation' and 'address' that would be tedious to manually store for each of their properties.

+1  A: 

I wouldn't store data in XML in the cookie - there is a limit on cookie size for starters (used to be 4K for all headers including the cookie). Pick a less verbose encoding strategy such as delimiters instead e.g. a|b|c or separate cookie values. Delimited encoding makes it especially easy and fast to decode the values.

The error you see is ASP.NET complaining that the headers look like an XSS attack.

stephbu
Good point, i'll keep the question open a little longer before accepting that answer :)
Per Hornshøj-Schierbeck
+4  A: 

Storing serialized data in a cookie is a very, very bad idea. Since users have complete control over cookie data, it's just too easy for them to use this mechanism to feed you malicious data. In other words: any weakness in your deserialization code becomes instantly exploitable (or at least a way to crash something).

Instead, only keep the simplest identifier possible in your cookies, of a type of which the format can easily be validated (for example, a GUID). Then, store your serialized data server-side (in a database, XML file on the filesystem, or whatever) and retrieve it using that identifier.

Edit: also, in this scenario, make sure that your identifier is random enough to make it infeasible for users to guess each other's identifiers, and impersonate each other by simply changing their own identifier a bit. Again, GUIDs (or ASP.NET session identifiers) work very well for this purpose.

Second edit after scenario clarification by question owner: why use your own cookies at all in this case? If you keep a reference to either the original object or your lightweight object in the session state (Session object), ASP.NET will take care of all implementation details for you in a pretty efficient way.

mdb
Yeah i hear you - i just added an edit to my question. I need 'all this data' to speed up things. The identifier CAN give me the whole object but the process of doing so is too slow, and nothing i can do about it since it's in an existing service i'm not to tamper with.
Per Hornshøj-Schierbeck
+1  A: 

Look into the View State. Perhaps you'd like to persist the data across post-backs in the ViewState instead of using cookies. Otherwise, you should probably store the XML on the server and a unique identifier to that data in the cookie, instead.

Chris
Also a good point, but the reason i don't use viewstate here is because there is a lot of new requests (non-postbacks) so the flow is not contained on a single page. I'm actually implementing this on an existing solution so i don't want to change the other pages.
Per Hornshøj-Schierbeck
A: 

You might look into using Session State to store the value. You can configure it to use a cookie to store the session id. This is also more secure, because the value is neither visible or changeable by the user-side.

Another alternative is to use a distributed caching mechanism to store the value. My current favorite is Memcached.

Alex Lyman