SP2010: solving the mysteries around form digest
There seems to be some mystery around a technique called form digest. Mainly because developers will get errors complaining about an invalid security state of their request. I’ll try to explain.
First, you need to know why form digest is there in the first place. It’s a security technique SharePoint uses to make sure that the data it processes is actually valid and secure data. What you don’t want for instance, is users creating their own forms and posting them onto completely different parts of your site. And sure, you’re users probably won’t be able to create forms at all, but what about sites which are exposed to the public? It would be kind of nasty if a scriptkiddy could create a form (or app for that matter) which spams your SharePoint site with comments you don’t want on there (spam or worse for instance).
Ok, so for those kind of things, there’s form digest. This consists of two parts: the first part is a FormDigestControl which has to be present on a SharePoint page when you want the postback to work. This control adds data to your postback which is then evaluated by the server. So the second part is serverside code which checks if the form digest data in your postback was correct or not. SharePoint can verify that the request actually came from the same SharePoint environment. And it goes even further, also checking if the request was made from within the same site.
So, you’re most likely to receive this error: “The security validation for this page is invalid” when you
a) don’t have a form digest control on your page or
b) are posting / saving data in a different site then where your page resides.
Is that it? No way around it? Of course there is, but you shouldn’t believe every solution out there!!!
There are some folks claiming you should set SPSite.WebApplication.FormDigestSettings.Enabled = false. Yeah sure, you COULD do that. If you want your entire webapplication to be vulnerable for cross site posting that is. Seriously, don’t touch that setting unless you have a very good reason to do so.
Then there’s running elevated (SPSecurity.RunWithElevatedPriveleges) and setting AllowUnsafeUpdates to true. Also bullocks. AllowUnsafeUpdates is primarily meant to allow GET requests to be processed. Those are unsafe by default, since there will never by any digest data to check anyway. So you need to explicitely enable processing those requests if you want to. A valid example is processing web service requests for instance. But you do not need this to safely process your post request.
So what is the correct way to do it then? Use the SPUtility.ValidateFormDigest() method. This will validate the current (and only the current) form digest, no matter what data is passed (or not). So you will need to do this each time you want to perform such an action. This is a much safer option, because you will be in control of when the form digest check will be bypassed (as opposed to just disabling the checks alltogether). And since outside users won’t have a clue as to when this happens, they most likely won’t be able to misuse it. Most likely, bypassing security measures is never 100% waterproof if you ask me (even when you think it is).