Different session Id from the same IP on the same time - c#

In my application every time a user lands on my website I check that user with it's session ID and make a insert(with all the details ip,browser etc) into the database if its a different session ID.
string sessionId = HttpContext.Current.Session.SessionID;
if (objDB.checkDuplicate("session", "sessionId", sessionId))
{
// code to make insert in database
}
But when checking database I am getting multiple inserts from same IP at the same time.
Can anybody explain why this happens?
NOTE : SESSION of the user is different so checkDuplicate() works fine but how can a user have a different session ID at the same time? (or such a sort span of time)

Most probably it's multiple people sharing the same connection over a router or proxy server.

More reasons (being behind router/proxy is most likely one) to have different session Id for same IP
restarting browser will make new session Id for the same user (as long it is set in session cookies)
opening separate browsing session (i.e. normal vs. private for IE, depending on configuration and browser tabs may be treated as separate sessions)
different users on the same computer
Another set of reasons for different session Id is based on failure to set persist session cookie between requests:
I think if there is no writes to ASP.Net session state cookie can be regenerated on every request (need to verify)
cookie could be disabled (rare, but possible)
cookie can be blocked (i.e. lack of P3P policy for pages/images in IFrame) or some other policy in browser
There are valid reasons to get multiple browser windows for the same sessionId for the same user (tabs in same "browser session", "open in new window/tab" with Ctrl+click ). You as site creator have to decide if you want to try to enforce "single session = single window" policy or deal with potentially multiple windows opened in the same session. There is no reasonable way I know to detect case when same session Id is used in different tabs, especially if you have to support GET requests (otherwise you can dump some addition ID into hidden field).

Related

Limiting user to one login session by unique ID in AuthCookie and checking against database table

I am creating a website that lets users run tests and hosts study content, I do not wish for any logged in user to be able to have more than one logical session. So essentially restricting simultaneous usage from multiple browsers or computers logged into the same account by invalidating any requests coming from any non-current/latest session. But I am not too sure on how to best hook into this with asp.net forms authentication.
I am thinking:
Create a db table called ActiveSessions, with rows: UserID, UniqueSessionID. Store this UniqueSessionID in the encrypted AuthCookie on the client.
If a user is not authenticated and logs in via standard login page /account/login etc. Create new UniqueSessionID and store it in the AuthCookie and in the ActiveSessions table respectively, overwriting any existing value. I presume I would have to decrypt and copy contents of the default AuthCookie forms authentication will issue, then create a new AuthCookie using this copied data and also insert my UniqueSessionID into it before returning it to the client.
In the event a request comes in for which the AuthCookie holds a UniqueSessionID that does does not match the one in the database or the record is missing for the respective user, invalidate the session and redirect browser to login page or kill session and issue error for Ajax requests.
Create some kind of scheduled service that cleans up records in the ActiveSessions table based on where User LastActivityDate exceeds some length of time etc.
Ideally I am hoping forms authentication provides some hooks where I can stick this logic in and avoid doing this with attributes over controllers/methods etc.
Also I wish to avoid using session state and its cookie entirely.
I had a very similar requirement. My situation was such that I had to make sure that user ID's were logged in from just one device at a time (Forms Authentication, by the way, not AD). When a user ID tried to log in to another device while still logged in to an existing device, it killed the session on their existing device while allowing them to log-in to the new device. The implementation I created has worked perfectly and so far, have found no flaws in the design. I wrote up a solution on my original post on Stack Overflow:
When the same user ID is trying to log in on multiple devices, how do I kill the session on the other device?

Is it safe/ok to use UserId as connection id and store it as a cookie

I have seen many examples for extendeding the CreateConnectionId for the signalR hub class such as these:
http://www.kevgriffin.com/maintaining-signalr-connectionids-across-page-instances/
Storing User On Login then Pushing Data On Demand
but does changing each user's connection_id to his UserId (keep in mind I am using the the standard asp membership provider out of the box) pose a security threat? I could see how it would be great to do this so I wouldn't have to keep an internal mapping from users to connection_id's but also thought it could have a security threat if I store it in a cookie on a user's browser.
No it is not safe and will eventually break SignalR.
The reason is that if you e.g. use the user's database id and store it in a cookie, the same connection id will be generated when you open a second tab in your browser (as the same cookie will be sent to the server).
This is obviously bad and will break SignalR as soon as you have two tabs or browser windows open, which is not mentioned in the articles you referenced. Additionally, as Icarus described, one could change the cookie and receive messages of other users.
A better way to do it is this:
Keep the default GUID connection id generator and instead add the connection to a group which is identified by your own id (e.g. database id or email address) after starting the connection. This way you can call Clients[emailAddress].doSomething() and it broadcasts to all open tabs of this user.
I'd adventure an answer and say Yes, this looks like a bad idea because cookies can be easily manipulated and a user may change it to some other random id and start receiving messages/data that aren't intended for him.

Cookie safety issues

How can I remember a user that is logged in without having a security issue? Currently, I am storing the id and a guid into two different cookies and compare them when there is no session alive. If it match then I re-create the session. Btw, both id and guid are nore encrypted.
Is this method safe enough, or should I follow a rather distinct way?
Since cookies can be easily stolen by use of XSS, does not matter if you place information in just one cookie or two, because a theft will take them all.
I have solved with a more complex procedure: I place one encrypted cookie divided in 2 parts (but 2 cookies will work as well), one fixed and the other variable each session. Both are saved also on server side to check: they are only session identifiers, no sensible information contained in the cookie, the correspondence with the user id is saved on the server.
If a fake user enters the account with a stolen cookie, the variable part (or cookie) will change, so when real user connects again he will not be able to enter and you will have the proof that an unauthorized access occurred: then you can delete the permanent session on server side (defined by the fixed part or cookie) in order to avoid any further access by the theft. The real user will re-login and create a new permanent session with a new cookie. You can also warn him that you saw a security flaw, suggesting him to reset password (operation that should never be accessible directly from cookie) or to use another browser for unsafe navigation.
If you save additional user information (user-agent, IP by location) you can check cookie validity also on them in order to avoid even the first entrance of the fake user.
I would recommend you using forms authentication for tracking logged in users in an ASP.NET application.

creating global session

i want to create a global session which will stay active until and unless we manually kill it. how to do this in asp.net with c#
what i am doing is
HttpContext.Current.Session["UserID"] = someValue;
but in this way the session is lost after some time.
You can set the timeout in web.config under system.web -> sessionState -> timeout. Not sure if you can have an infinite session though.
Also, you might be interested in the Application object which stores things in the "application's session" instead of the user's. Comes to my mind because you speak of a "global" session.
What's the application for this? Sounds like you're actually trying to use the session as a persistent storage, which will however only seemingly work even if you manage to set timeout to never or 5 years or whatever - because sessions will be "timed out" once the application is restarted. You might still get around that, but you might be better off looking for real persistence solution like a database. I may be totally off guessing your application for that of course.
Store the data in the Application state rather. It will stay there till you remove it, or the app dies/recycles/ends.
Usage:
HttpContext.Current.Application["Foo"] = "bar";
As nicolas78 says use session timeout configuration property to control the session expiry after user inactivity. In case, you are facing a requirement where session should be active as long as browser is open, there are two ways -
Use cookie to store some token and then re-construct your session state using the token if session gets expired. For example, user details can be recovered from user store if user id is stored in token. At worst, you may have to move your entire state to the database.
Keep the ASP.NET session state but keep it alive by firing AJAX requests from browser. I would suggest to fire such request after n/3 interval where n is your session timeout (ensuring at least three requests are made so even if two gets lost or falls on edges, one gets through).
Perhaps you're after profiles?
http://msdn.microsoft.com/en-us/library/2y3fs9xs.aspx
Profiles live beyond the session and are usually used to store per-user settings that the user can edit, such as their contact details and application preferences.
Profiles can be used with both anonymous and authenticated users. When an anonymous user signs in, their anonymous profile can be migrated into an authenticated profile (i.e. one that is attached to their user name).
Good walkthrough here: http://quickstarts.asp.net/quickstartv20/aspnet/doc/profile/default.aspx

What is the difference between a Session and a Cookie in ASP.net?

What is the difference between a Session and a Cookie?
What circumstances should each be used?
Sessions
Sessions are stored per-user in memory(or an alternative Session-State) on the server. Sessions use a cookie(session key) to tie the user to the session. This means no "sensitive" data is stored in the cookie on the users machine.
Sessions are generally used to maintain state when you navigate through a website. However, they can also be used to hold commonly accessed objects. Only if the Session-state is set to InProc, if set to another Session-State mode the object must also serializable.
Session["userName"] = "EvilBoy";
if(Session["userName"] != null)
lblUserName.Text = Session["userName"].ToString();
Cookies
Cookies are stored per-user on the users machine. A cookie is usually just a bit of information. Cookies are usually used for simple user settings colours preferences ect. No sensitive information should ever be stored in a cookie.
You can never fully trust that a cookie has not been tampered with by a user or outside source however if security is a big concern and you must use cookies then you can either encrypt your cookies or set them to only be transmitted over SSL. A user can clear his cookies at any time or not allow cookies altogether so you cannot count on them being there just because a user has visited your site in the past.
//add a username Cookie
Response.Cookies["userName"].Value = "EvilBoy";
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(10);
//Can Limit a cookie to a certain Domain
Response.Cookies["userName"].Domain = "Stackoverflow.com";
//request a username cookie
if(Request.Cookies["userName"] != null)
lblUserName.Text = Server.HtmlEncode(Request.Cookies["userName"].Value);
sidenote
It is worth mentioning that ASP.NET also supports cookieless state-management
Cookie is a client side storage of your variables. It stored on client machine by browser physically. It's scope is machine wide. Different users at same machine can read same cookie.
Because of this :
You should not store sensitive data on cookie.
You should not store data that belongs to one user account.
Cookie has no effect on server resources.
Cookie expires at specified date by you.
Session is a server side storage of your variables. Default, it stored on server's memory. But you can configure it to store at SqlServer. It's scope is browser wide. Same user can run two or more browsers and each browser has it's own session.
Because of this :
You can save sensitive data in session.
You should not save everything in session. it's waste of server resources.
After user closes browser, session timeout clears all information. (default is 20 minutes)
A cookie is an identifaction string stored by a server (who has a domain) in the browser of the user who visits the server/domain.
A session is a unit of maybe variables, state, settings while a certain user is accessing a server/domain in a specific time frame. All the session information is in the traditional model stored on the server (!)
Because many concurrent users can visit a server/domain at the same time the server needs to be able to distinguish many different concurrent sessions and always assign the right session to the right user. (And no user may "steal" another uses's session)
This is done through the cookie. The cookie which is stored in the browser and which should in this case be a random combination like s73jsd74df4fdf (so it cannot be guessed) is sent on each request from the browser to the server, and the server can assign and use the correct session for its answers (page views)
The cookie allows the server to recognize the browser/user. The session allows the server to remember information between different page views.
Sessions are not reliant on the user allowing a cookie. They work instead like a token allowing access and passing information while the user has their browser open. The problem with sessions is that when you close your browser you also lose the session. So, if you had a site requiring a login, this couldn't be saved as a session like it could as a cookie, and the user would be forced to re-login every time they visit.
Its possible to have both: a database primary key is hashed and stored in a lookup table: then the hash is stored on the client as a cookie. Once the hash cookie (hahhahaha :) is submitted, its corresponding primary key is looked up, and the rest of the details are associated with it in another table on the server database.
The main difference between cookies and sessions is that cookies are stored in the user's browser, and sessions are not. This difference determines what each is best used for.
A cookie can keep information in the user's browser until deleted. If a person has a login and password, this can be set as a cookie in their browser so they do not have to re-login to your website every time they visit. You can store almost anything in a browser cookie.
Session is a server side object,
which transfer or access data between page call.
Cookies is a object which is client side/client machine which store some text information of browser and server.
There appears to be some confusion regarding what a session cookie is.
Firstly, when we are talking session cookies - it has nothing to do with ASP.Net sessions. Likewise, session cookies have nothing to do with server side processes or caching.
A session cookie is nothing more than a cookie that expires when the browser session expires. To create a session cookie - don't put an expiration date on it. Doing this stores the cookie in memory and is disposed of when the browser is disposed.

Categories

Resources