I'd like to find out what session ID hijacking protection is built into the current version of ASP.NET.
I recently saw this very informative article that explains how session security can be enhanced by implementing an additional layer that encodes the IP address and user agent header into the session id. These details are then verified on each subsequent request.
It seems that this article was written for ASP.NET 1.1 so I'd like to know if anything similar is now built into ASP.NET. Is it still of any benefit to implement such an additional layer?
Thanks.
Check out this snippet from the Session Overview documentation:
System.Web.SessionState.HttpSessionState.SessionID values are sent in clear text, whether as a cookie or as part of the URL. A malicious user could get access to the session of another user by obtaining the SessionID value and including it in requests to the server. If you are storing sensitive information in session state, it is recommended that you use SSL to encrypt any communication between the browser and server that includes the SessionID value.
http://msdn.microsoft.com/en-us/library/ms178581.aspx
It seems to me that this means that there is no security baked into Session, so you probably shouldn't use Session as a security measure. Instead, I would recommend relying on ASP.NET security (authentication, authorization).
Here is an article from the Patterns & Practices group on general security recommendations for ASP.NET.
http://msdn.microsoft.com/en-us/library/ff649100.aspx
Hey, I have also been looking for ways to reduce the risk of session ID hijacking. I read Jeff Prosise's article as well and I thought it could be useful; however, just like you, I was looking to see if the same approach applies for modern versions of the framework (his email wicked#microsoft.com doesn't work btw)
jkohlhepp, I don't agree with your post (or maybe I don't understand it):
you probably shouldn't use Session as a security measure. Instead, I would recommend relying on ASP.NET security (authentication, authorization)
As far as I'm concern asp.net authentication relies on Session IDs (except cookieless which seems to be worse: See Dino Esposito's opinion)
So, that pretty much put us where we started.
Related
I understand that it is possible to hijack the asp.net session by stealing the asp.net session cookie. I guess that I'm thinking of stealing the cookie as it is transmitted over unsecure wi-fi.
Other than using SSL are there standard ways of securing this information? Or preventing the hijacking of the session?
Sadly, the only way to prevent cookies from being used in a replay attack is to send them over HTTPS since that ensures that the cookie itself is encrypted and, therefore, kept from prying eyes.
Have you seen Jeff Atwood's blog entry about this matter, Breaking the Web's Cookie Jar? Jeff focuses more on the concerns from the user's perspective, but it's worth reading anyway. Here's what he says folks can do today:
So here's what you can do to protect yourself, right now, today:
We should be very careful how we browse on unencrypted wireless networks.
Get in the habit of accessing your web mail through HTTPS.
Lobby the websites you use to offer HTTPS browsing.
This is very broad advice, and there are a whole host of technical caveats to the above. But it's a starting point toward evangelizing the risks and responsible use of open wireless networks.
There probably needs to be some sort of new, more secure approach for cookies going forward, but who knows if there will be enough traction to warrant such change or enough interest to spurn adoption. For web applications where security is paramount - think medical information websites, financial websites, and so on - the only plausible option is to require HTTS for the user's entire browsing session.
There is no easy solution to that problem, other than requiring the authentication information with every page request (which isn't practical and is worse from a security standpoint in an unencrypted environment).
In order to maintain state while using HTTP (which is stateless), something like a cookie must be used. If that cookie is being sent unencrypted, it can be used by somebody else.
As a side note, if you have to pick between two evils of having a session hijacked and having the password compromised, you would rather have the session hijacked. That is why it is crucial that changes like password modifications require re-authentication so that a hijacked session can't take over the account itself. Of course that can also be circumvented if the authentication credentials are not encrypted.
I'm developing an ASP.NET web site for some small business. The site needs a password-protected area where the site owner will manage the site content. For the rest of the world, the site is completely read-only.
I've designed and implemented the following scheme:
A user wants to access some protected page.
Every protected page inherits "AdminIface" master page, that alters the UI so that user knows he's on a protected page, and checks the security cookie. If no cookie or wrong cookie: redirect to auth.aspx.
Auth.aspx generates a big random number using RNGCryptoServiceProvider, then sends it to the client + password form.
User enters the password.
Client-side JavaScript combines random seed + password, calculates MD5 of the resulting string, posts MD5 to the server.
Server compares the random seed with the value hold by Session, if OK it combines random seed + password, calculates the MD5, compares MD5.
If the checksum matched – the server generates one more big random number to be used as a security cookie.
Server stores the security cookie in Session object, and sends the cookie to the client who's now considered authorized.
The correct password is stored as a string constant in the auth.aspx source.
Is this scheme OK?
P.S. I know AD+Kerberos is much better, however on the godaddy's shared hosting I've got no privileges even to create one more application.
I would just hard code the user authentication into the web.config. This means you can still use the Membership controls. A really good example can be seen here. No database required, nor Membership provider. If you have one user (or very few users) then this is a pretty good option.
If you are worried about the authentication details sitting in the web.config, then you can encrypt specific sections of the web.config.
This would appear to be a much simpler solution than you have implemented.
It sound ok. Standard HMAC stuff. However your weaknesses:
Application: relying on javascript and sessions
Security: using a new codebase
Depending on your requirements you might be ok. having said that I strongly suggest using forms authentication, which overcomes these issues and much more.. and it is fairly easy to use.
Ummm, why not http://en.wikipedia.org/wiki/Basic_access_authentication with https (or even without)?
-- What's the real scenario of a threat?
Your method seems a bit hand-rolled. The usual rule is to try to use an existing security system rather than inventing your own. Inventing a new authentication mechanism that is really secure is known to be a very hard problem.
Many intelligent people (namely the Software Engineers who created WEP) have tried and failed at creating their own security authentication mechanisms and failed. The possibilities for screwing up your own "custom" security authentication are endless (no offense, but it is an extremely difficult problem to handle even for security experts).
I think it's best to use something that is proven to work such as an SSL certificate based authentication method.
What is wrong with TLS/SSL? It would provide many benefits here, the least of which is some thread of site->user authentication.
As kind of already mentioned, why not just use forms authentication with an SSL cert - dead easy to set up (particularly for one user) and you know that it's been tested... You don't know what you've potentially missed.
We're creating a new consumer/public-facing ASP.Net web app. There are two concerns:
--Use cookie or cookieless forms authentication?
--If we decide not to use cookies at all, how would you store the data that would otherwise be stored in the cookie (Customer ID, AffiliateID, etc.). Does the ASP.Net authentication framework track something like CustomerID?
For a normal web app there is no good reason to use cookieless authentication - Fear of cookies died out about a decade ago.
For actual data, the session object is generally a better choice than individual cookies - The session cookie is a single value that effectively gives you a key to whatever session data you have stored on the server. There are certain specialized cases where there are problems with using session, for example in multi-server deployments, but in for most applications it is simple and adequate.
The standard forms authentication system does track the username - generally this is enough to look up whatever data you need from your database if you don't want to keep anything in the session.
If you're doing authentication, cookies are the usual method. It's very rare these days that people will have cookies turned off because so many sites already depend on them.
Having said that, ASP.NET does support "cookieless" authentication. Basically it just adds the authentication token as a parameter on the URL. It parses all outbound URLs to ensure that they also include the token information. Personally, I wouldn't bother with this and just go with requiring cookies. There are a few additional headaches when trying to go cookieless (for example, it can make SEO that much harder, because the search engines will see a different URL every time it crawls the page).
We have an ASP.NET MVC application for which we have developed our own custom RoleProvider class. Without caching it will access the datastore for every request - bad. The only caching option we can find is (in web.config) via cookies stored on the clients' machines. My two questions are:
Is this secure (even with encryption enabled)?
Will the cookie information be transmitted with every web request - thus, potentially, slowing the application more than accessing the datastore every time?
Does anyone have an alternative route? I understand that caching this information in the Session is also bad?
If you have developed your own custom RoleProvider class, you can do your own data caching, e.g. using the ASP.NET cache. This is more flexible than using Session as a cache, since it will work even on pages that don't have session state enabled.
I don't agree with Wyatt Barnett's comment that:
The downside for using the Session
... the fact that Session storage is
very violate and not particularly
reliable
It's OK for a cache (whether Session, the ASP.NET Cache or something else) to be volatile - you just need to repopulate it when required.
To answer your questions:
It's as secure as the encryption used to encrypt the cookie. If you're relying on FormsAuthentication, it need be no less secure than the Forms Authentication ticket.
The cookie will be transmitted with every request. So there is a potential performance hit if users can have a very large number of roles, and the potential to exceed the maximum cookie size supported by the browser.
While the idea that querying the DB each request is inefficient is true, but remember that SELECT performance on properly indexed tables in modern DBs is blazingly fast, so I would first take some measurements to be sure that this scenario actually negatively effects performance versus theoretically could negatively effect performance at a later date.
The downside for using the Session isn't so much the overhead (minimal) as the fact that Session storage is very violate and not particularly reliable. You can easily lose the session and still have a logged in user, for example.
That said, a good way to settle in the middle here would be to cache the user's roles per request using the HttpContext.Items collection. This will limit to one SELECT per request, which is probably reasonably efficient (cf measurement above) while avoiding the other storage issues--such as a fat, insecure cookie or some rather violate Session-based solution.
The cookie information will in fact be sent from the browser to your web server with every request, that's just how cookies work, but as long as the size of the cookie is reasonable it shouldn't have too much of an impact on performance. If you are using forms authentication I would recommend storing the roles in the forms authentication cookie as described in this blog post. In that case, you are just adding data to a cookie that already exists. You should be aware that there is an upper limit to the amount of data you can store in that cookie however, as described here.
Working inside the context of an ASP.NET application I am creating a page that will be able to execute database scripts against one of many databases in our environment. To do this we need to prompt the user for a username/password combination, this value can be used for all servers without issue.
The question is where is the most secure location to store this information? We need to store it temporarily as when they are on this specific page they could be executing hundreds of scripts, over multiple postbacks. From what I can tell I have 3 options and I'm not sure what is the best. Below is my take on the options, what is the recommendation of everyone here? What is the most secure, while still being friendly for the user?
Store Information In Viewstate
One of the first ideas we discussed was storing the information after being supplied by the user in the ViewState for the page. This is helpful as the information will only exist for the lifetime of the page, however, we are unsure of the security implications.
Store information in Session
The next idea we had was to store it in session, however, the downside to this is that the information can be made available to other pages inside the application, and the information always lingers in memory on the server.
Store Information in Application
The last idea that we had was to store it in the Application cache, with a user specific key and a sliding 5 minute expiration. This would still be available to other pages, however, it would ensure that the information is cached for a shorter period.
Why?
The final question that is important is "Why are you doing this?". Why don't we just use their Lan id's? Well we cannot use lan id's due to the lack of network support for delegation.
S0 what is the recommended solution? Why? How secure is it, and can we be?
Update
Great information has been discussed. TO clarify, we are running in an intranet environment, we CANNOT use Impersonation or Delegation due to limitations in the network.
In my opinion the natural place for this is the Session.
I'm not sure why you seem to be fearing "other pages inside the application" (you control the appliciation, don't you?), but if you really are, you could use some sort of encryption before you store it.
But if you are going to do that, the data could live in the ViewState as well.
I don't like any of these ideas, but totally hate the viewstate idea.
I don't know how many databases you are attaching to, but if there is a limited number, I kind of wonder if handling your authentication and authorization in a standard secure manner, then connect to those databases via integrated security using identity impersonation with an account that has minimal permissions.
The ViewState approach is good but has the problem that you are giving out the username and password to the client. Even if you encrypt it, if some attacker has the encryption key, the situation will not be very good.
Regarding the Session and Application approaches, I don't think Application approach makes sense. Data is user specific, so Session should be the way to go. It'll go away as soon as user's session is closed. By the way, if you chose to store it at the server, use SecureString class.
As John MacIntyre wrote you should use integrated security and impersonation for this.
If for some reason you can not use it and you are going to provide your own login page, use by all means SSL to encrypt the traffic between the browser and your server. Using the ViewState approach is also completely insecure if you do not use SSL, there are tools to view the contents very easily. From the methods that you enumerate the best one would be to use the Session state. You can offload saving the session state from your web server memory and save that data in a database that you can secure the way you want. If you don't like the way these work you could even write your own session state provider and apply the security you need there.
Storing in Viewstate increases your exposure because the password will be flying around the internet again and again. It's up to you if encryption is good enough to address this risk.
Using Application or Session both keeps the password in the server. As mentioned above SecureString will keep people from simply reading passwords out of memory. Session will scale to more users, and probably more importantly to multiple servers much easier than Application. Unless you are sure you will never use more than 1 web server I would not use Application, as it will be up to you to synchronize all the servers.
Never store passwords!
Rather store the hash of a password. See: http://en.wikipedia.org/wiki/Crypt_(Unix)#Library_Function.
I'm aware this does not answer the question, but the more programmers who ignore this advice, the easier it will be for criminals to steal data. Don't let your organization become a news story.
The username/password really shouldn't be stored anywhere.
You store a live database connection, preferably from a pool in your Session object. You only need the username/password as long as it takes to log into the database.
While another page can use the live connection, it doesn't give anyone else permanent access to the database as you would by storing a username/password.