Search code examples
asp.netformssessioniisviewstate

Viewstate verification failed for the first form submit of new sessions


We have a website running on ASP.NET 4.5.2 that throws the below viewstate error on the first form submit of a new session, specifically and only when that form submit is the first postback on the site. Any subsequent form submission seems to be fine, until you close the browser and start a new session. It also doesn't happen if you navigate elsewhere on the site first and then go to the form; it's only if you go directly to the form from the start (i.e. navigating directly to the signin page).

Event code: 4009 
Event message: Viewstate verification failed. Reason: The viewstate supplied failed integrity check. 
Is authenticated: False 
Authentication Type: Forms 
Thread account name: IIS APPPOOL\.NET v4.5 
Exception message: Invalid viewstate.

This has been reported/demonstrated in Edge and Chrome, but not Firefox or Internet Explorer.

EDIT: Turns out that we were able to identify that Edge and Chrome do not have the ASP.NET_SessionID session cookie on initial browsing of the site. After a postback, the session id appears in the cookies and the form works again. This does not happen in Firefox, Firefox has the .NET session id from the first page load. This session id is being used as the ViewStateUserKey, and this probably explains the how of the error, but not the why. Why does Chrome not have the session id until after a postback?

I've already read everything on the internet I can find on this error, so let me note a few things based on other suggestions I've seen:

  • Adding a machine key to the web config file does not help. We tried it already. Also, this site is not on a server farm, it's running on a single web server.
  • I've seen suggestions that app pool recycling or memory limits on the server could be involved, but the server in question is running nowhere near the limits of its resources, and the error can be replicated consistently; if it were related to app pool events or memory issues I would expect it to be more sporadic.

Other information in case it is relevent:

  • server is running IIS 8 on Windows Server 2012 R2
  • authentication setting in the web config is <authentication mode="Forms"><forms name="XXXXXXXXXX" loginUrl="SignIn.aspx" timeout="525600" /></authentication>
  • session state in web config is <sessionState mode="InProc" cookieless="false" timeout="20" />

Any ideas would be greatly appreciated!

EDIT: Someone asked about how the forms are submitted. Here's a sample of the form code from one of the form pages that I can reproduce the error on, giftcard.aspx.

<form name="aspnetForm" method="post" action="./giftcard.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/[gibberish]" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>
<script src="/WebResource.axd?[gibberish]" type="text/javascript"></script>
<script src="jscripts/formvalidate.js" type="text/javascript"></script>
<script src="jscripts/core.js" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/WebResource.axd?[gibberish]" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function WebForm_OnSubmit() {
if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
return true;
}
//]]>
</script>

We're using an asp:Button control for the submit, as below:

<asp:Button ID="btnContinue" CssClass="btn-primary btn-GCcontinue" runat="server" Text="Continue" OnClick="btnContinue_Click" />

This example would be typical of the forms on the site.


Solution

  • Turns out that the answer was related to Samesite cookies. We had recently updated our session id cookie to use samesite=none in an attempt to fix issues with our payment processing that we suspected were related to Chrome's samesite changes. When we did that, we didn't realize that we needed to specify Secure as well, and while I'm still not sure how the lack of Secure led to the specific behavior we observed, updating our session cookie to use SameSite=None; Secure; seems to have fixed it, and Chrome now recognizes ASP.NET_SessionId from the first request.

    Side note, because our version of .NET is so old, we're using a rewrite in the app config that we found here https://www.coderfrontline.com/chromes-samesite-cookie-changes-are-breaking-apps/ and now that I look again it totally says to use Secure but at the time we didn't notice that, just copied the sample verbatim. So make sure you add Secure if you're using HTTPS.