MyNameIsKo
MyNameIsKo

Reputation: 2301

Prevent session variables from being overwritten in new tabs

I've inherited an old ASP.Net Webforms application that makes heavy use of Session variables to store the database record IDs of user-submitted applications. This has caused some severe issues where users open up forms for different applications in multiple tabs, unwittingly overwriting information in one app with data meant for another.

Common usage throughout the application looks something like this:

// Get the application ID from the database
var appID = Convert.ToInt32(Session["appID"]);

// Update application using the above ID
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);

// Redirect to another step of the form
Response.Redirect("/application/step-2");

Since this issue persists across numerous pages of the application, the solutions I've found are less than ideal (detailed at the end of this post).

My question: is there any way for me to prevent new tabs from overwriting existing session variables without having to rewrite Session access across the entire application?

Here are the solutions I've found that are more a less a last resort due to how much of the application would need to be changed:

*The above solutions were found on the related post: asp.net - session - multiple browser tabs - different sessions?

Upvotes: 0

Views: 3378

Answers (2)

John Wu
John Wu

Reputation: 52260

Sounds like it is not feasible to rewrite the code to store data somewhere other than session.

If that's truly the case, perhaps your easiest option is to add code to your site to display an error whenever the user opens up the site in a second tab, or if activity in a different tab modifies the AppID.

Prevent multiple tabs completely

Here is one way to do it, high level:

  1. Add code to Application_EndRequest to output a "microsession" cookie containing a timestamp or random nonce with each and every page. Note: You must be careful NOT to output this cookie for resource requests, e.g. images or CSS. Only output if the current request is for a page.

  2. Add a snip of javascript to your common.js file (or whatever location will cause it to run for every page in your site) which does the following:

    a. On page load, grab the microsession cookie and store its value in a Javascript variable

    b. Occasionally check the microsession cookie to see if it has changed. You can do this with a timer, or you can just check when the user is submitting any form. Be aware that some devices will pause scripts when the tab loses focus, so if you are using a timer, you should also check when the tab gets focus again.

    c. If the cookie has changed, that means that the user requested a page from your site but in a different tab. Display an error. At that point you can either force them to log off or just Session.Abandon() and redirect them to the home page, where a new, clean session will automatically be constructed for them.

Allow multiple tabs as long as AppID doesn't change

If you want to allow multiple tabs and just want to cause an error when there is an unexpected change in AppID, you can set the microsession cookie to a hash of the AppID instead of the nonce. That way the error will only trigger if the AppID changes. If there is more than one session variable you need to check, you can concatenate them (string concatenation is fine) before generating the hash.

Upvotes: 1

John Wu
John Wu

Reputation: 52260

It sounds like AppID is not logically a property of your session. It is a property of the page, or possibly of a workflow.

If you need to store a property of a page that persists between postbacks, you can store it like this:

this.ViewState["AppID"] = appID;

And to perform the update

var appID = (int)ViewState["appID"]
UpdateDB("UPDATE Application SET Title='MY TITLE' WHERE id=" + appID);

Be sure to secure your ViewState or else malicious users could tamper with the AppID and update someone else's record.

ViewState is stored in the page itself, so will not leak between tabs.

Upvotes: 1

Related Questions