Answered by:
Does Anti XSRF Tokens or Session ID affects ViewState validation?

Question
-
User-924931093 posted
I built a site that's running on a two load-balanced servers (web-farm), after a while I had to do the following:
at the login page, when the user enters user-name and pass, if the user is valid then I'm abandoning the session and creating a new one as follows:
protected void btnLogin_Click(object sender, EventArgs e) { var Token = Guid.Empty; try { if (IsValidCaptcha()) { string email = txtEmail.Text.Trim(); string pw = txtPassword.Text.Trim(); AbandonSession();//Delete any existing sessions var newSessionId = CreateSessionId(HttpContext.Current); //Create a new SessionId SetSessionId(HttpContext.Current, newSessionId); Token = SecureLogin.Login(email, pw, LangCode); } else { lblMsg.Style.Add("display", "block"); } } catch (Exception) { Token = Guid.Empty; lblMsg.Style.Add("display", "block"); } if (Token != Guid.Empty) { Response.Redirect($"HiddenPage.aspx?token={Token.ToString()}", false); } else { lblMsg.Style.Add("display", "block"); } } protected void AbandonSession() { Session.Clear(); Session.Abandon(); Session.RemoveAll(); if (Request.Cookies["ASP.NET_SessionId"] != null) { Response.Cookies["ASP.NET_SessionId"].Value = string.Empty; Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-20); } if (Request.Cookies["__AntiXsrfToken"] != null) { Response.Cookies["__AntiXsrfToken"].Value = string.Empty; Response.Cookies["__AntiXsrfToken"].Expires = DateTime.Now.AddMonths(-20); } } private string CreateSessionId(HttpContext httpContext) { var manager = new SessionIDManager(); string newSessionId = manager.CreateSessionID(httpContext); return newSessionId; } public void SetSessionId(HttpContext httpContext, string newSessionId) { try { var manager = new SessionIDManager(); manager.SaveSessionID(httpContext, newSessionId, out bool redirected, out bool cookieAdded); } catch(Exception ex) { SmtpMailer.SendMsg(ex.Message + ex.StackTrace + ex.InnerException, "", ""); } }
This is one of the requirements for the site and I can't change it at all (changing the session after login to the site).
after applying this approach, I started getting this error almost in every page in the site (every now and then).
Event code: 4009 Event message: Viewstate verification failed. Reason: The viewstate supplied failed integrity check. Event time: 1/22/2019 2:53:36 PM Event time (UTC): 1/22/2019 7:53:36 PM Event ID: 5ffacfa116224c9f8f516ead8a89cc55 Event sequence: 378 Event occurrence: 1 Event detail code: 50203 Application information: Application domain: /LM/W3SVC/2/ROOT-1-131926597583461452 Trust level: Full Application Virtual Path: / Application Path: ........... Machine name: .............. Process information: Process ID: 6624 Process name: w3wp.exe Account name: IIS APPPOOL\.............. Request information: Request URL: ............../qConsole/CampaignGroup-Launch.aspx Request path: /qConsole/CampaignGroup-Launch.aspx User host address: .............. User: Is authenticated: False Authentication Type: Thread account name: IIS APPPOOL\..............
I double checked (a) the machine key /decryption key is the same on both servers in load balancing, and (b) that they are not set to auto generate
and also I added this code to Global.asax
protected void Session_Start(object sender, EventArgs e) { Session.Timeout = 60; }
and I have this set in the web.config file
<sessionState timeout="25" />
Important Note: I'm using anti xsrf tokens in the Master Page to protect against xsrf, and it's using ViewState variables as following:
protected void Page_Init(object sender, EventArgs e) { if (Session["CurrentUser"] == null) { Response.Redirect("/"); } //protect against XSRF attacks var requestCookie = Request.Cookies[AntiXsrfTokenKey]; Guid requestCookieGuidValue; if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue)) { // Use the Anti-XSRF token from the cookie _antiXsrfTokenValue = requestCookie.Value; Page.ViewStateUserKey = _antiXsrfTokenValue; } else { // Generate a new Anti-XSRF token and save to the cookie _antiXsrfTokenValue = GenNewId(); Page.ViewStateUserKey = _antiXsrfTokenValue; var responseCookie = new HttpCookie(AntiXsrfTokenKey) { HttpOnly = true, Value = _antiXsrfTokenValue, Expires = DateTime.Now.AddMinutes(10.0) }; if (FormsAuthentication.RequireSSL && Request.IsSecureConnection) { responseCookie.Secure = true; } Response.Cookies.Set(responseCookie); } Page.PreLoad += master_Page_PreLoad; }
Here where I'm getting the error and being redirected to the Error page:
protected void master_Page_PreLoad(object sender, EventArgs e) { try { if (!IsPostBack) { // Set Anti-XSRF token ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey; ViewState[AntiXsrfUserNameKey] = Session.SessionID.ToString(); } else { // Validate the Anti-XSRF token if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue || (string)ViewState[AntiXsrfUserNameKey] != Session.SessionID) { Response.Redirect("/Error"); } } } catch (Exception ex) { SmtpMailer.SendMsg(ex.Message + ex.Source + ex.StackTrace); } }
I have a feeling that the issue I'm having revolves around the feature I added (creating new session-id after the login page), any ideas or thoughts are really appreciated.
Thanks
Thursday, January 24, 2019 4:03 PM
Answers
-
User475983607 posted
Session, XSRF tokens, and ViewState are all affected by load balancing. Especially InProc session, since Session exists in memory on the server that created the Session. The antiforgery tokens and ViewState are encrypted by a web server and set to the browser using cookies and input fields. The load balanced servers must share the same machine key and scheme used to encrypt the data otherwise the servers cannot decrypt antiforgery tokens created on the other server.
Also the error message can happen if a user times out.
Is authenticated: False
Or JavaScript is used to update a control on the page like a dropdownlist.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, January 24, 2019 4:15 PM -
User-893317190 posted
You could refer to the link below for similar solution for csrf token.
If you still have problem, please debug the code in your local machine to see whether it works.
Best regards,
Ackerly Xu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, January 31, 2019 5:36 AM
All replies
-
User475983607 posted
Session, XSRF tokens, and ViewState are all affected by load balancing. Especially InProc session, since Session exists in memory on the server that created the Session. The antiforgery tokens and ViewState are encrypted by a web server and set to the browser using cookies and input fields. The load balanced servers must share the same machine key and scheme used to encrypt the data otherwise the servers cannot decrypt antiforgery tokens created on the other server.
Also the error message can happen if a user times out.
Is authenticated: False
Or JavaScript is used to update a control on the page like a dropdownlist.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, January 24, 2019 4:15 PM -
User-924931093 posted
Thanks for the reply, I double checked that they share the same machine key and scheme used to encrypt the data, using the IIS Console -> Machine key section and they're identical.
is this what you mean? or there's somewhere else to check?
Thursday, January 24, 2019 4:21 PM -
User-924931093 posted
Also the error message can happen if a user times out.
Is authenticated: False
what do you mean by this?
Thursday, January 24, 2019 4:23 PM -
User475983607 posted
This error...
Event message: Viewstate verification failed.
...can also happen if JavaScript modifies input elements in the browser like adding to a dropdownlist.
Thursday, January 24, 2019 4:31 PM -
User-924931093 posted
Thanks for your replies, I double checked all what you suggested, but the problem still persists, do you have any thoughts on the way I'm validating the XSRF token in the master page? or maybe the logic should be different? or maybe the way I'm changing the Session ID at the login page as i explained in the main post is somehow affecting the ViewState?
Thursday, January 24, 2019 6:20 PM -
User-893317190 posted
Hi basel@Simboliq,
If you don't set value in Session, it will not automatically set SessionId cookie back to browser.
And if asp.net doesn't set back sessionId cookie, the property Session.SessionId will always return different value.
Please check whether you set any value to Session before using Session.SessionId.
Also, because you are using web-farm, please check the sessionmode of your app and ensure two servers share the same session.
https://www.c-sharpcorner.com/UploadFile/225740/introduction-of-session-in-Asp-Net/
Best regards,
Ackerly Xu
Friday, January 25, 2019 4:07 AM -
User-924931093 posted
Hello Ackerly, Thanks for your reply and suggestions,
I did check all the suggested ways to resolve it, here is what i did and my findings:
1- I checked the machine.config files on both severs (since its running on a web-farm) and there is no tag for MachineKey value to change
%windir%\Microsoft.NET\Framework64\[version]\config\machine.config
2- I checked both servers -> IIS configs. [Machine Key] section and I made sure that they do have the same validation and decryption keys and they're not set to AutoGenerate keys
3- I re-generated a new values for [Machine Key] using PowerShell and updated the values [as described in this link]
4- I checked that the MachineKey values in web.config that matches the values in step 3
5- I changed the code in master page (in the main question up)
from this
protected void master_Page_PreLoad(object sender, EventArgs e) { try { if (!IsPostBack) { // Set Anti-XSRF token ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey; ViewState[AntiXsrfUserNameKey] = Session.SessionID.ToString(); } else { // Validate the Anti-XSRF token if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue || (string)ViewState[AntiXsrfUserNameKey] != Session.SessionID) { Response.Redirect("/Error"); } } } catch (Exception ex) { SmtpMailer.SendMsg(ex.Message + ex.Source + ex.StackTrace); } }
to this [replaced SessionId as a value for ViewState[AntiXsrfUserNameKey] with CurrentUser.Code]
protected void master_Page_PreLoad(object sender, EventArgs e) { try { if (!IsPostBack) { // Set Anti-XSRF token ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey; ViewState[AntiXsrfUserNameKey] = CurrentUser.Code; } else { // Validate the Anti-XSRF token if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue || (string)ViewState[AntiXsrfUserNameKey] != CurrentUser.Code) { Response.Redirect("/Error"); } } } catch (Exception ex) { SmtpMailer.SendMsg(ex.Message + ex.Source + ex.StackTrace); } }
The problem still persists!
This is driving me crazy :(
Monday, January 28, 2019 2:53 PM -
User-893317190 posted
You could refer to the link below for similar solution for csrf token.
If you still have problem, please debug the code in your local machine to see whether it works.
Best regards,
Ackerly Xu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, January 31, 2019 5:36 AM