How does one set a custom server variable? - c#

In my web application I test for a condition on one page and want to retain the results of the test for a specified duration (such as 5 minutes). I can do this with a cookie, of course, but just in case a user has disabled cookies, I'm thinking a custom server varible might do the trick. I've heard about this, but I haven't been able to find out to do it.
Alternatively, maybe a session variable might be better? There's no inherent way to expire these, right? How long would such a variable survive before IIS tosses it?

Asp.Net has session state. Each Asp.Net Page has a Session property. You can also access it via HttpContext.Current.Session, though there is a subtle difference that won't matter until it bites you (which see my answer to the question, Difference between Session and HttpContext.Current.Session.
The default session state configuration is in-memory. That means that if your web site is served up from something like an F5 Networks Big IP (load balancer) cluster, unless the load balancer is set up to be 'sticky' (meaning that once assigned to a machine in the cluster, you'll always hit that machine unless it goes down or is otherwise removed from the cluster).
If your clustered web site doesn't have sticky sessions, your session state will vanish when your request hits a different machine...and then reappear when another request hits the original machine. You can guess how much fun that can be.
There is built-in support for SQL Server session that you can enable in your web.config. Once set up that way, you're using SQL Server as the backing store for session state. That solves the server farm issue noted above, but does so at the expense of hitting a SQL Server each and every time a session state value is accessed. That slows down access considerable, especially if the session size large. Oddly, executing a SQL query and shoving a 500kb session blog across the network every time you access a session state setting can negatively impact performance. Who knew? [Don't ask how we found that out].
There are other solutions to the problem: ScaleOut's products come to mind (e.g., ScaleOut SessionServer).
Or you can roll your own session state provider using something like an AppFabric cache.
Another "feature" of using SQL Server sessions state is that anything going into Session must be ISerializable.

You can't set a server variable; instead, using Session, which is tied to the current user, is the best approach for user-based data. For application-based data, you can consider cache. So assuming the former, do:
Session["Key"] = MyValue
Note that session lasts 20 minutes; if you have to have exactly 5 minutes, you can use cache, which you can explicitly expire at 5 minutes:
Cache.Add(CurrentUserID.ToString() + "Key", "Value", .. TimeSpan.FromMinutes(5));
You can use the ID of the current user to make the cache value specific to a user, or use cookies, but set HttpOnly=True on the cookie object. An HTTPOnly cookie is only on the server and never accessible on the client, as such:
varcookie = New HttpCookie("Key", Value);
cookie.Expires = ..;
cookie.HttpOnly = true;

Related

ASP.CORE Session using a DistributedSqlServerCache

We use a DistributedSqlServerCache to store user session data but I have noticed some unexpected/strange behaviour. So I was wondering how a DistributedSqlServerCache works under the hood to help me understand the behaviour that I am seeing.
When a user arrives at the site, immediately a DB entry is inserted, as seen below in img 1.
When the user logs out or the session times out, the session data is cleared (replaced with some arbitrary default value) and the ExpiresAtTime is also reset, as seen below in img 2.
Again, another user arrives at the site, and a new DB entry is inserted, as seen below in img 3.
But this time, if the application pool is recycled or the IIS is reset, then the below (img 4) is the result in the database:
It appears that the original session has not been emptied and also a new session is started.
For completeness, here's the code we use in StartUp.cs:
services.AddDistributedSqlServerCache(o =>
{
o.ConnectionString = "conn_string...";
o.SchemaName = "dbo";
o.TableName = "PS_PWD_SESSIONS";
});
services.AddSession();
Unless I’ve got the wrong end of the stick, this doesn’t make sense to me. I would be very grateful for any insight into this behaviour.
It's best not to worry about this too much. ASP.NET Core knows what it's doing. I think the behavior you're seeing is a result of session key vs. session id. The session id is tied to the actual physical session, persisted in the database here. However, the cookie that gets sent to the user contains only a session key. This session key is always valid and never expires. The client then always sends back this cookie with the same session key, and ASP.NET Core internally decides whether to restore the previous session or create a new one, based on whether the session has expired, etc.
In other words, the underlying data in the actual database doesn't necessarily reflect existing "sessions", at least from a client perspective. To the client, their session lives forever, but in the database it could be deleted. If there's no active session in the database to correspond with the client's session key, then ASP.NET Core just creates a new one.

Get unique session ID/key on server side

I'm almost sure what I'm looking for exists, but I didn't finding on Microsoft documentation nor here.
I just want to get an unique ID (a string or a number, I don't really mind) from a client in ASP.NET 4.5, on the server side. I want this ID linked to a session, so different for each system that would connect to my server (like multiple computers or same client with different browsers), but the same if a user open multiple tabs on the same browser on my server.
I already looked on:
System.Web.UI.Page.ClientID: It is the name of the control (so always "__Page").
System.Web.UI.Page.UniqueID: It returns the same.
Session.LCID: I'm not sure to what it refers to, but it is the same if I connect to my server with different browsers.
Session.SessionID: Change each time I refresh the page or open it in a new tab.
Request.AnonymousID: Is null.
So all my attempts gave me an ID that changes everytime or never. Is there any way to get something from session ?
What you are looking for is in fact the Session.SessionID, however it comes with a caveat.
From MSDN:
When using cookie-based session state, ASP.NET does not allocate storage for session data until the Session object is used. As a result, a new session ID is generated for each page request until the session object is accessed. If your application requires a static session ID for the entire session, you can either implement the Session_Start method in the application's Global.asax file and store data in the Session object to fix the session ID, or you can use code in another part of your application to explicitly store data in the Session object.
I suggest using REMOTE_ADDR / REMOTE_HOST values from ServerVariables collection. These would have same values even if the user is using multiple browsers and uses different sessions from the same machine. Note that REMOTE_HOST might not always have a value.
References :
https://msdn.microsoft.com/en-us/library/system.web.httprequest.servervariables(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx

Saving ViewState and ControlState to Session in ASP.Net for a customer facing site

I am thinking of using the following code to save all viewstate and controlstate to session for ASP.Net pages in a website that uses 'in process' sticky sessions with 30 minutes as session timeout.
On the surface, this appears a very good option to optimize page load times in user's browser.
Is there any catch/drawback that I may be missing in following this path for a customer facing ASP.Net website?
protected override PageStatePersister PageStatePersister
{
get
{
return new SessionPageStatePersister(this);
}
}
From a security standpoint, Session hijacking should be a concern, especially if there is anything even remotely sensitive stored in the session; this can be mitigated by using SSL to encrypt the delivery of Session data including the SessionID itself.
From a memory standpoint, the more stuff you put into memory, the less there is of it to go around for everything else. Is 30 minutes too long of a timeout, maybe or maybe not? How many concurrent users does the system have? Will that grow substantially and, if so, when?

HttpSessionState Where, How, Advantages?

You see the code below, how I did use the session variable;
So the three questions are:
Where are they stored? (Server or Client side)
Are they unique for each web page visitor?
Can I remove it using ajax or simple js code when my job is done with it? or it will be removed automatically..?
.
sbyte[][] arrImages = svc.getImagesForFields(new String[] { "CustomerName", "CustomerSurName" });
Dictionary<string, byte[]> smartImageData = new Dictionary<string, byte[]>();
int i = 0;
foreach (sbyte[] bytes in arrImages)
{
smartImageData.Add(fieldNames[i], ConvertToByte(bytes));
i++;
}
Session.Add("SmartImageData", smartImageData);
Read more about sessions here. To answer your questions:
Depends on your configuration (in-process, Session State Server etc.), but always server-side.
Yes, each visitor gets a unique cookie.
You can remove it client-side by removing the session cookie (usually ASP.NET_SessionId), or server-side by calling Session.Abandon(). Also, a session times out after a certain (configurable) period of inactivity.
Session variable are stored on the Server? You can configure other state management mechanism (E.g Database).
They are unique for each user session. It will be removed when Session times out.
Session state information is stored on the server and not on the client side. When the session expires, this session information is removed completely and automatically. You can change the session expiration duration through web.config file. Session data is unique for each user. You can always use it using ajax or change it or even remove it.
If you want the session data persistent to be persistent, you can configure your database for storing the session information. You can even configure a state server to store the session data.
The session is usually stored on the server (depending on your server/application configuration). Each unique browser connection is allocated a session id which the server uses to associate the client with a unique server session on subsequent connections. The session id is passed to the client to store as either a cookie, or as a paramater attached to each url request to the server.
It is used as a means of preserving client state with the server between HTTP calls.
The session expires after a configurable time of inactivity. However in .NET you can call Session.Abandon() to end the current session.

XSS to change ASP.NET session state

I am developing the application that stores current user and user's role to session state (System.Web.SessionState.HttpSessionState Page.Session).
if (Session["username"] == null)
Session.Add("username", User.Identity.Name);
if (Session["isAdministrator"] == null)
Session.Add("isAdministrator", User.IsInRole(domain + "\\Domain Admins"));
After I check these session states in code behind for granting permissions to some excecution:
if ((bool)Session["isAdministrator"] || computer.Administrators.Contains(Session["username"].ToString()))
My question is next: how safe that mechanism is? Is it possible to change the session states using some JavaScript for example or some how else?
Thanks :)
If User.Identity.Name is set, why do you need to put it in the Session? Why don't you just call User.IsInRole(domain + "\\Domain Admins") directly (or wrap it in a helper)? It looks to me like you're using Windows Authentication, so setting the username in the session is redundant.
As for your XSS question, the session stores the session ID in a cookie, so in theory an attacker could be sniffing the HTTP traffic or inject JavaScript code into your pages, get a hold of the cookie, then use it and impersonate another user.
It is not possible to change the session state using javascript or other client-side mechanisms, as the state is only stored on the server. However, it is, as others have pointed out, possible for a malicious user to hijack a session by getting hold of the contents of the session cookie.
ASP.NET is designed with this weakness in mind - the session ID is suitably long and hard to predict. Also, the session cookie is marked as HTTP ONLY, which means that most modern browsers will not allow javascript code to access it.
In general I would say this is very safe from XSS attacks. ASP.Net, by default, tracks a users session based on a Cookie which contains the users session ID. You can see this if you open your browsers cookie list and look for ones from your site, there will be one there named ASP.Net Session something... The SessionID's unique, and not incremental. Probably some variance of a GUID.
For added security you can also specify, in your web.config, how long to keep a users session alive. If you are dealing with sensitive information you might want to set this timeout to be relatively short period of time, maybe 10 minutes of inactivity, the default is 20 minutes. You can find more info # http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.timeout.aspx.
<system.web>
<sessionState timeout="10" />
</system.web>
--Peter

Categories