Is it possible to hack someone's session variables and create a new shadow user?
What are the common ways of avoiding such surprizes?
SSL certificate installation or ....?
Short answer... it depends.
Session in ASP.NET can be stored in a variety of ways (InProc / SQL Server / State Server) etc... another thing to note is how the client session is maintained (query string value, cookies etc...)
As the poster in this answer suggests
Can we hack a site that just stores the username as a session variable?
One thing you could do when you authenticate the user and store their name in Session, would be to also store some other information about them. e.g. Their UserAgentString, their IP Address and if a different IP or UserAgentString attempted to interact with the session, you could invalidate it.
Anything is possible, however by default it's hard.
Generally you hijack a session by stealing the session cookie and recreating it on another machine. However in order to do this the web site must be vulnerable to Cross Site Scripting (which you can mitigate against with Server.HtmlEncode when you echo user input back). If if you do end up vulnerable the ASP.NET session cookie is marked as HTTP Only, which means, if a browser supports it, it is not accessible to access from client side scripts (although Safari ignores this setting).
Related
I originally used static variables to store some user information when a user is browsing my site. I had issues where occasionally a user would navigate somewhere and see a different users name on the page. I switched to using session variables to solve this, but the same problem occurred. I then thought making the session variable names unique in some way would solve the problem, e.g. instead of
Session["userId"]
I changed all session variables to append the unique username of the user when they are created and referenced, so they are:
Session["userId" + Context.Identity.User.Name.ToString()]
So far I've had no reports of the issue, but is this actually going to work? Is there a simple way to protect sessions so the variables don't leak between users? I'm confident with ASP.NET code (webforms specifically) but have only encountered the session issue as more users use the site. I don't have much control over IIS settings as the site is built via AWS Elastic Beanstalk, so it's mostly default IIS settings.
This should work fine, but I suggest storing username or user profile information in cookies or local storage since as you mentioned when lot of users logged in it maintains session for them on server memory(I believe session is in-memory by default not in-proc or redis). This is not scalable as if millions of user logged in or you create load test server considerable memory will be taken by session management. Few hundred users however is not much overhead.
You can store information at user browser using sessionStorage like:
Setting value
sessionStorage.setItem("user_name", "test");
Getting Value
var userName = sessionStorage.getItem("user_name");
It can store javascript object or json too.
Cookies are old way to store info at user end :
Creating cookie
document.userCookie = "username=John Doe";
reading cookie
document.userCookie //"username=John Doe"
Forms authentication also provide encrypted & secured cookies which is maintained with session which is also good if user profile information is sensitive data.
Sorry, I can't write comments for your question, but:
Same issue happed to Java developer with AWS Elastic Beanstalk:
https://forums.aws.amazon.com/thread.jspa?threadID=84027
First, I suggest you try to set no-cache for your HttpResponse (temporary solution), than
I suggest you try to play with your IIS proxy settings.
If it didn't help (and you're using load balancer) - refuse from using inproc settings like in this topic:
User on wrong session
PS. You really don't have to make session variable names different - Session uniqueness is guaranteed by ASP.NET setting different Session_ID for each session.
I'm looking into storing some security sensitive information (a users effective permissions for our web application) in a session-resident object, to reduce database queries while performing permissions checks throughout the app.
I understand that the session is stored server-side, and not directly accessible to the client under normal circumstances. ASP.net's other persistence mechanisms can be theoretically defeated, by modifying viewstate or cookie values client-side, but these kinds of cryptography implementation flaws should not expose session-state.
What degree of control over your server would an attacker need to modify data in a clients session-state? Assume they have a sessionID, and an ASPAUTH cookie.
For instance:
A remote attack, like a modified POST or other handler call to a
page?
Would an attacker with programmatic access to IIS (WMI mabey?)
be able to access and change session-state in the same or another app pool's memory?
Would an attacker need to be able to post code to my app, in order to manipulate session memory?
I know these kinds of questions often rely on mistakes in my code, so by all means assume I've written the worst, most insecure code ever (I haven't, but...) and do things like change session in a constructor or life cycle event.
Since we don't know exactly how your code is implemented, all we can do is guess.
First, Session should NEVER be used for security sensitive things. Yes, it's true that a client can't directly read session, there are other factors to consider.
Session cookies are not, by default, encrypted and are passed as plain text.
Session Fixation attacks are easy to accomplish
If a session cookie is hijacked, or even guessed, then it doesn't matter what the users account is, they will get whatever security rights you assign via that cookie.
Session is unstable, and IIS can kill sessions whenever it feels like, so you end up with the situation where a user is still logged in, but their session is lost due to many possible reasons. So now their security is also unstable.
There are many other, more appropriate ways to do what you want, Session is NEVER an appropriate method.
Other methods that would be appropriate include...
Using the user data field of a FormsAuthentication ticket to store the information
Using a custom Claim with a claims based authentication, like ASP.NET Identity, WIF, or IdentityServer.
Using the asp.net Cache to hold the temporary information, based on identity (not session) and adding a cache eviction timeout.
and many more...
Session variable can be a security risk. It is always better to secure your session variable.
Few links you should take into consideration...
Securing Session State
http://msdn.microsoft.com/en-us/library/ms178201%28v=vs.140%29.aspx
http://www.dotnetnoob.com/2013/07/ramping-up-aspnet-session-security.html
http://www.codeproject.com/Articles/210993/Session-Fixation-vulnerability-in-ASP-NET
http://www.dotnetfunda.com/articles/show/730/session-security-in-aspnet
I agree with Erik views.
regards
I was wondering if HttpContext.Session uses cookies to store data. A work colleague told me that in a mobi site, phones generally do not have cookies and therefore you don't have session. I always thought session is data that is stored on the server side and is not dependant on client side objects please explain if I am wrong.
I read this.
In ASP.NET; you have a Session cookie. This cookie is used to identify which session is yours; but doesn't actually contain the session information.
By default, ASP.NET will store session information in memory inside of the worker process (InProc), typically w3wp.exe. There are other modes for storing session, such as Out of Proc and a SQL Server.
ASP.NET by default uses a cookie; but can be configured to be "cookieless" if you really need it; which instead stores your Session ID in the URL itself. This typically has several disadvantages; such as maintence of links become difficult, people bookmarking URLs with expired session IDs (so you need to handle expired session IDs, etc). Most modern phones, even non-smart phones, support cookies. Older phones may not. Whether you need to support cookieless sessions is up to you.
If your URL looked like this:
http://www.example.com/page.aspx
A cookieless URL would look like this:
http://www.example.com/(S(lit3py55t21z5v55vlm25s55))/page.aspx
Where lit3py55t21z5v55vlm25s55 is a session ID.
You can learn more about ASP.NET's session state here
The session data is stored on the server, but it also stores an id string in a cookie to identify the user.
If cookies are not supported, the id string can't be stored, and the server can't pair the session when the user makes another request.
The session id is just a number generated by the server (either from a counter or randomly), so it doesn't contain any information from the data that you store in the session object.
(The application can also be configured to put the session in the URL instead of in a cookie. This enables you to use sessions without cookies, but it ruins your nice URLs.)
Nowadays it can be both.
Server Session
Server Side session already explained in the others posts. The session is stored on the server but it need a cookie to store an indicator of who is requesting the session value.
Client Session
The new concept of WebStorage defined by W3C shows how a client side session is nowasays needed.
Here is the HTML5 implementation of a WebStorage:
https://code.google.com/p/sessionstorage/
This is a tricky question in some ways, as it is a bit of both.
The session state, itself, is stored on the server. But, you need some type of indicator on the client to use it. Normally, this is a server cookie, which is very thin and is basically a GUID for the session and nothing more. But, you can set up sites to pass the session ID in the URI, so it need not be a cookie.
Not sure how phones deal with the session cookie concept, but since I can log in, and do not see IDs in URIs, I assume there is a mechanism, even if it does not handle user cookies.
Session id is by defauld stored as cookie. You can also configure your session to pass its id as a query parameter ("cookieless").
For various reasons I am fed up with ASP.NET session state and I'm trying to do it myself (separate question coming soon related to why I'm fed up and whether it's feasible to do it myself, but for now let's assume that it is).
Security concerns aside, it seems like tracking sessions involves little more than storing a cookie with a guid and associating that guid with a small "sessions" table in the database, which is keyed on the guid and contains a small number of fields to track timeout and to link to the primary key in the user's table, for those sessions that are linked to registered users.
But I'm stuck on a detail with the cookie, in the case the user's browser is not set to accept cookies. It seems to me that each time a user accesses any page that has session state enabled, ASP.NET must determine whether the browser supports cookies. If there already is a session cookie sent with the request, obviously it knows cookies are accepted.
If not, it seems like it needs to check, which as I understand it involves trying to write a cookie and redirecting to a page that tries to read the cookie. So it seems, when a user with cookies turned off visits several pages of a site, that ASP.NET
(a) has to do this round-trip test for every page the user visits, or
(b) has to assume the browser accepts cookies and create a record with a (provisional) session id for the user on each page -- and if session state is supposed to be persistent, it seems it has to write that initial session id to the database on each page.
But (a) sounds crazy and (b) sounds crazy also, since we would quickly accumulate session ids for all these single-page sessions. So I'm thinking there must be some other trick/heuristic that is used to know when to do the round-trip test and/or when to actually create a record for the session.
Am I wrong to be perplexed?
(To be clear, I'm not talking about implementing a custom storage solution within ASP.NET's pluggable session state system. I'm talking about skipping ASP.NET's session state system entirely. My question is a more detailed version of this one: Implementing own Session Management in ASP.NET.)
Session behaviour is set through the sessionState element in web.config. In the sessionState element the HttpCookieMode can be set to one of UseUri, UseCookies, AutoDetect, UseDeviceProfile.
UseUri and UseCookies tell ASP.NET explicitly how to handle storing the session identifier. If UseDeviceProfile is used then the behavior is determined by whether the user agent supports cookies (not whether they are enabled or not).
AutoDetect is the interesting case that you are interested in. How ASP.NET is handling the auto detection is explained in Understand How the ASP.NET Cookieless Feature Works. In that article you will see that they have 5 different checks they do. One of the checks is, as you mention, to set a cookie and do a redirect to see if the cookie exists. If the cookie exists, then the browser supports cookies and the sessionID cookie is set. However, this is not done on every request because another check they do before tring to redirect is is check to for the existence of any cookies. Since after the initial set-cookie and redirect the sessionID cookie will be set then the existence of the cookie lets ASP.NET know that cookies are supported and no further set-cookie and redirects are required.
Well, cookies are a standard mechanism of web authentication. Do you have any reason at all why you wouldn't want to use them? Are you sure you're not trying to invent a problem where there isn't any problem?
Most serious websites I know of require the browser to accept cookies in order for the user to be authenticated. It's safe to assume that every modern browser supports them.
There's an interesting article about cookieless ASP.NET that you should read.
EDIT:
#o.k.w: By default the session state is kept by ASP.NET in-process (read: in memory). Unless told explicitly by the configuration to store the session in the database (SQL Server is supported out-of-the-box), this won't result in a database hit. The stale session states will get purged from the in-process storage. Unfortunately, with default ASP.NET settings every cookieless request will result in a new session being created.
Here's a detailed comparison of available session storage options: http://msdn.microsoft.com/en-us/library/ms178586.aspx.
We have an application that among other things, checks the existence of a cookie and reads and decrypts the contents of the cookie. Though the data stored inside the cookie is not sensitive, it has been encrypted via TripleDes encryption. A question was raised today whether the cookie saved on a single PC, could be copied on to another PC and whether the web application would detect the presence of this copied cookie on another machine, and ultimately decrypt what it would have on the original PC.
My question is this:
We use the standard ASP.NET implementation to save cookies (i.e via HttpResponse), does the index.dat file prevent the transplant of a cookie from one machine to the other? What if the index.dat file was also transported and copied over, or is there some internal structure inside index.dat that ties a cookie to a specific machine?
Absolutely. This is one way that cross-site scripting (XSS) attacks work:
I inject javascript into a page
I wait for someone to look at the page
The javascript I injected sends me your cookies
I login as you and do bad things
This particular issue bit SO during the private beta.
Yes, stealing cookies is a common technique to steal a session from a user.
Some sites try to bind a cookie to the IP of the client, but this fails in the face of big corporate proxies with multiple out-bound interfaces or other non-residental setups.
Even if everything else is ok, if someone can get physical access to the user's machine, they could copy the cookies to another machine.
E.g just clone the disk if needed!
In addition to the other answers. Never trust anything coming from the user of a web app, regardless of whether it's encrypted.
This ties into the idea of validate input on both client and server. Don't trust that the validation on the client was done.