Storing xml data in a cookie - c#

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.

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.

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.

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.

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.

Related

What is the best way to store some immutable and highly accessed data in C#?

Some background - I am working in a project which requires a kind of headshake authentication. The external service will send a request with a Token, and I will answer with Validator. Then it will send a second request containing the same Token and the data I should store in my database. The token is also used to get a couple extra fields that are required to insert the data in the database. Due to several project constraints and requirements, this "api" is implemented in Serverless (Azure Functions).
Since there are only 100 and something token-validator pairs that are not often updated (I will update manually every month or so), I have decided about not querying the database every time I get an incoming request. Normally I would simply use caching in C#, but since I am working with Functions, the code will be executed in multiple changing processes, which means no shared cache. I also think that using a cache service, such as Redis or Azure Cache would be an overkill.
My current solution - Currently, I am storing the data in a Hashtable that maps a Token to a ValidatorModel object that contains the validator and the extra fields I require. It works pretty well, but since it is a big C# object, it is a pain to update, the IDE lags when I open it, etc. I also don't know if it is a good idea to have it hardcoded in C# like that.
What I have been thinking about - I was thinking about storing a binary protobuf file that contained my Hashmap object. I am unsure if this would work or perform well.
My question - What is the best way do store such data and access it in a performatic way?

are cookies the only way of storing session variables?

I want to store a user setting(language). so i can get the corresponding resources when the page loads. I figured cookies would be the way to go, but it's just not an option, too difficult since i have tried and tried without success.
After 2 days i want to give up on cookies and see if there is another way I can achieve the same goal
i've read this article http://msdn.microsoft.com/en-us/library/ms178581.aspx
but im not sure if I can achieve what I want using that.
What alternatives for cookies could i use in my situation?
Depending on the level of persistence you're looking for, there are a couple of other ways you can do this. The first is to use session to hold these settings. However, if you use session the settings will only live as long as the session does. If your website has some kind of authentication interface, you can store the settings in a database relative to the username used for authentication. If you don't have authentication involved and simply want to remember that the user came with a particular computer/device, you can achieve the same result by footprinting the system (not trivial) and storing that footprint in the database related to any settings it would encounter.
If those options are not available to you, then cookie will be your only remaining alternative.
An other alternative to using cookies to keep a session ID is to use cookie-less session management, which is mentioned in the article that you linked to. A cookie won't be kept on the client machine with the session identifier -- instead, it will be in the query string. It's definitely an "uglier" solution, but it's one of the few options you have. You can either keep a cookie that's sent up with each request, or stick something on the query string to identify the request.
Either way, you need some way for your server to pick up the identifier and retrieve your session data -- whether it's getting the ID from a known cookie or a known query string value.
I mean, there are probably other ways -- keeping a hidden value on each and every page, but I think that just gets even "uglier". You want to keep that information out of the page/information that you're rendering.

How can I change or remove HttpRequest input arguments in a HttpModule

Is it possible to change or remove http request form inputs in an httpmodule?
My goal is to create a security IHttpmodule that will check the request for reasonable values, such as limits on acceptable input and query parameter length, or use the AntiXSS Sanitizer to remove threats, log potential hack attempts, etc. before a request is passed on to a processor.
Because this is a cross cutting concern I'd prefer to find a solution that applies to all requests and affects all ways request values could be accessed, Reqest.Form, Action(model), Action(FormCollection), HttpContext.Current.Request.Form, etc.
I'm using MVC and have considered creating custom model binders to clean the data before creating the model instance. But that would be application specific, require remembering to register every model binder and only apply to Action(model).
I suggest you do not sanitize input at this stage as it may lead to interesting issues. I learned this the hard way.
What would you sanitize? Code injection (script/html)? Sql Injection? Something else? The sanitization is linked to what you're doing. So, if you're setting up code that records what was in the HTTPRequest for each request into a database, it makes sense to work against injection, but removing malicious code, or modifying it won't store the data as it was provided, and you're going to get inconsistent data.
Your code should look at the context of what's being done with these inputs, rather than re-assigning raw input data.
If it's going into a database, make sure it's not going to allow for injection attacks. If it's embedding the data onto a page, make sure it's escaped such that you can't include scripts or change the HTML with it. If it's an emailer, make sure you can't insert a new line charecter in the email field and have SMTP send to multiple addresses.
It's all about the context, because there is no catch all for all the exploits. So, keep your raw inputs raw, but filter them based on what you're going to do in that part of your code.
How did I learn this the hard way? Back when I was learning PHP and web security, I made a script that investigated all HTTP headers, cookies, request variables, ip, page address, and otherwise. It then filtered them through various pre-defined filters based on what I wanted, and passed them into the required function/object. For instance, age was a number so I would make sure to assign it to my object after filltering through the sanitize-age function. This was fine for some cases, but when you have multiple contexts in which that data can get used, escaping against SQL just doesn't cut it, and escaping HTML entities stores the data in a way that wasn't originally presented if I'm placing it into a database. Now, if that column needs to be filtered against XSS, then go ahead and update that specific part of the database with that, but not the raw data.
This is simply my opinion, I do not have resources that indicate this is a best-practice.

Dynamic output cache

I wonder if there are any cache engines or if someone has a good solution that can handle these requirements:
It should store plain HTML fragments of a page like the standard Output cache in asp.net
The HTML may contain dynamic content from a database
When an object is updated in the database all the cached HTML fragment containing that particular object should be destroyed and re-cached next time it will be requested.
There is a separate admin tool to handle all data in the database so I can easy store the Id’s in a cachetable when an object is invalid. I can also make a request to a page that destroy all cached HTML fragment for that object.
But when I write the markup, how could I do to store and retrieve a particular segment from the cache? Of cause I could do this in code behind and have the markup in a string but I don’t want that. I want to have the markup as intact as possible.
I'm assuming this is all within an ASP .Net page. I think your situation is simple enough to where you can write this caching mechanism yourself:
Make your SQL query as usual
Use the results to output your aspx page
Store the results in a static variable or static "Cache" class, this should persist from request to request
Future requests would use your stored results, unless they are invalidated as you mention they would be. (In my experience, a 1 minute time expiration can work well).
If you want to get more complicated, and preserve the cache even if IIS is restarted: You could easily use an XmlSerializer and write your results to a file instead of using static variables.
You have two problems to consider:
Number 1: Cache invalidation. This can be solved using cache dependencies (see http://msdn.microsoft.com/en-us/library/system.web.caching.cachedependency.aspx ) which will allow things to be invalidated and recached as data changes (automatically!).
Number 2: Cache storage. For this, just use the standard ASP.Net cache API using HttpContext.Current.Cache (or a suitable abstraction). That supports the dependency system as mentioned above.
The ASP.Net cache implementation is pluggable so you can change the storage mechanism between in memory, files, SQL databases, Memcached (via Enyim) or Microsoft Velocity for example. Each cache store has different reliability that you can pick and choose based on your requirements.

How to store user entered values across a website using C#?

I am currently working on a website that will have a high volume of traffic on it. The website has only 4-5 pages on it but I need to pass values selected on page 1 over to page 2 where more values are stored and so on until the user gets to page 5 where all values are passed to a third party system using XML.
Currently I use a dictionary object with roughly 20 keys stored in a single session object to hold the values across the different pages. I do this because some of the values are not just simple values like 'name' or 'age' values but can be complex like holding a dataset of results from an XML call on page 2.
I have read everywhere that global variables are bad so I am wondering if there is an alternative to using Sessions for this example? I cannot use a database to hold these values because of the way some of the values need to be stored (i.e. my variables are not just strings/ints). If I was to use global static variables how could I ensure the global variables are unique for each user?
Thanks for your thoughts.
Rich
** Edit 1 **
I am storing the current sessions in ASP.NET Session State and not inproc. I am just trying to figure out if what I am doing is bad practice or just generally accepted as an ok way of doing things. For example on the second page I get a XML result that I store as a dataset in my session for use on page 3/4 of my site. Should I be store/passing this info another way?
I cannot use a database to hold these
values because of the way some of the
values need to be stored (i.e. my
variables are not just strings/ints).
You actually can. You can serialise you object graph and store it as binary column in the database.
Additionally you can have this functionality out of the box and still using SessionState.
Here is an article on how to Store Session State in Sql Server.
So I would recommend to use Session but store the session state in the database.
Sessions are the right choice. The "global variables are bad" argument is a good one, but it's describing global variables, not session variables and pertains to how you organize data being passed among methods within your application. Storing data between pages can be done in only one of three ways:
Store the data in hidden fields or cookies (so everything gets passed back and forth for each page request). You could do this by just serializing your XML and other fancy data, but it sounds like a terrible idea.
Store the data in a database, flat file. This is a fine idea, but you'd still have to do the serializing work yourself.
Store the data in a session. This is exactly the same as option #2, except that C# is doing the serializing for you, and then saving the results in a flat file.
You do not have to do any work to separate the data of one user from another. Every visitor gets a unique session, and the data you store there won't ever be applied to another user (excluding a malicious attack such as a hijacked session).
I would think session is the appropriate place to put things that are relevant to your 'session'. It is true that over-using/abusing session can bite you with excessive memory consumption, but the alternatives can be a bit slower, just depending. Also, if you use SessionStateService or store the Session in SQL Server, you have slow-down in serializing/deserializing the session objects on each request.
You can use ViewState, but that means all of the data will get serialized to the HTTP Form, which means it will get passed back and forth on subsequent requests. Also, I think ViewState gets dropped from one ASP.NET form to the next, so unless you are on the same form, that won't work.
You can store the data in the database. One way is to have Session use SQL Server. If I were to use a database for this problem, I don't think I would use session in SQL Server though simply because if you store it yourself, then you could recover previously entered data.

Categories