How secure are ASP.net security cookies - asp.net

My understanding is that ASP generates a cookie to authenticate a session. However, if that cookie is sent back and forth over a non https channel, can't I spoof it simply by spoofing the cookie? Can the cookie be locked to a particular IP or other machine fingerprint?

Sessions in ASP.NET aren't authenticated - authentication is entirely separate. By taking a session cookie and recreating it yes you can hijack the session, and if you lift an authentication cookie then you can authenticate as a user (which is why, by default, authentication cookies expire) - see http://msdn.microsoft.com/en-us/library/ms178581.aspx
The security note is quite clear;
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.

At my last job we worked around this by tracking the user's session ID (we appended a guid to the URL as a query string, there are other ways) in a database where we would also store the ip address which made the request. For all subsequent requests (anything with a session ID, a requirement to get any sensitive information) we simply check the session ID and the ip making the request against the values stored when we authenticated and set up the session. Request.UserHostAddress is a little harder to spoof. There is some overhead, but it is way more secure than cookies.

Related

How to protect GET methods for .net application if the cookie is stolen

How to protect GET methods if the cookie is stolen since Antiforgery Token only protects the POST methods? The web application can return sensitive information via GET method.
I am using .AspNetCore claim based identity. I was trying to use Postman to view the content of the GET method, but I cannot get the it to work.
I assume this is theoretically possible. An authorized user cookie can be hijacked by a man sit in middle right?
The site is secured by SSL and I think the .AspNetCore claim based identity is session based cookie. What are the chances to break in to execute the GET methods and get returns values. How to secure the application?
It should never get to that point
Don't use just a cookie to validate a user. You should use several cookies based on each session, such as the device name or id, the device's IP address, a session ID stored in their browser, potentially something stored in their local data (permanently stored even if cookies are deleted) that validates that particular PC etc. There are plenty of other methods of security a user's identity.
However, if you use a session cookie and nothing else to authenticate a user, then you should probably revise how your application secures its users first. Because if that session cookie is stolen, then it's a bad sign for your user.

What would happen with session in the following situations?

If the session is stored in proc
The user logs in, closes the browser directly and reopens it after an hour. Would he need to log in again?
If the web application uses cookies and cookies are enabled on the users browser...
If the web application uses persistent cookies and cookies are enabled on the users browser...
If the web application uses cookies and cookies are disabled on the users browser...
If the web application uses persistent cookies and cookies are disabled on the users browser...
If session is stored in state server and situations are the same, then what would happen?
When a session is created (assuming it is a normal session), a cookie is sent to the browser that looks something like this:
SESSION_ID=437b930db84b8079c2dd804a71936b5f
Sessions can be used without cookies if the session identifier (in the example above, 437b930db84b8079c2dd804a71936b5f) is passed around as request parameter instead of a cookie; however, this is rather uncommon and it is generally considered bad practice.
All session information is stored server-side, and the session identifier is used behind-the-scenes to decide which set of information should be recalled (if any) for each request. Thus we get to your questions.
If the web application uses cookies and cookies are enabled on the users browser...
If the web app uses cookies and cookies are enabled on the browser, then there should not be a problem. With a standard session implementation, the cookies will be non-persistent, though, so the user will need to login again if he/she completely closes all instances of the browser.
If the web application uses persistent cookies and cookies are enabled on the users browser...
If the session-id is stored in a persistent cookie and user's browser respects that by persisting the session identifier cookie to the disk, then the session identifier will be sent even if the browser is fully closed and restarted. However, please be aware that most web frameworks have a garbage-collector-like system that deletes data for sessions that have showed any activity over a certain amount of time. So, for example, let's say my website requires activity at least once every 4 hours to keep a session active. If I login, receive a persistent cookie with my session ID, close my browser, and come back 5 hours later, then I will need to login again because my session information would have been cleared from the server even though my session ID cookie was persistent.
If the web application uses cookies and cookies are disabled on the users browser...
Bad news bears. You will either need to find a way to use a cookieless session (passing an identifier as a parameter for each request), or you will need to ask the user to enable cookies. There is no way around this.
If the web application uses persistent cookies and cookies are disabled on the users browser...
Same situation as #3. If the user has cookies disabled, you are out of luck. Either they need to enable cookies (at least for your site), or you need to find another way to pass around information between requests.
Session is stored in server memory (unless a state server or persistant store is used) but relies on a cookie to identify the session. If cookies aren't available then session won't work since there is no way to identify the user. Cookieless sessions can be used to get around this. Cookieless sessions aren't recommended as they can be hijacked with the session identifier in the url.
If an expiration isn't set on the cookie then it will be lost once the user closes all browser instances (they share memory) and not just the one visited through the website.
If the user has cookies disabled, then cookies aren't available for use by the application. People aren't as worried about cookies now as they were in the late 90's (lots of "security" people raised warnings that cookies could be used to store all sorts of things on your computer, even viruses).

Does Forms Authentication protect from session hijacking?

I have ASP.NET MVC app that uses Forms Authentication. After user is authenticated, in response he will receive forms cookie that contains auth information. Now regarding the forms cookie: It is encrypted by a machine key and it is protected from tampering by signature. I also use HTTPS... However, what if somehow I get the cookie and try to make request from another client (meaning that the request will be made from another IP address)?
It seems to me that this scenario will work. Are there any ways to defend from this kind of attack?
If you are using HTTPS everywhere on your site and set requireSSL="true" on your system.web/authentication/forms element in web.config, you are instructing the browser to only pass that cookie back over an HTTPS connection. This will protect against the vast majority of traffic sniffing-based session hijacking attacks and you should definitely use it if your site is HTTPS only.
Forms Authentication is inherently stateless. The server is encrypting the following information and storing it client-side: CookiePath, Expiration, Expired, IsPersistent, IssueDate, Name, UserData, Version. Assuming your machineKey hasn't been compromised, the client will just see this as a blob of encrypted data. When it presents that blob to the server again, the server decrypts it and converts it back into a FormsAuthenticationTicket, validates the fields in the ticket against config, verifies that the ticket isn't expired, etc. and decides whether to treat the request as authenticated. It doesn't 'remember' anything about which tickets are outstanding. Also note that it doesn't include the IP address anywhere.
The only real attack vector I can think of if you are HTTPS-only, take care to protect your machineKey, and set the forms auth cookie to requireSSL would be for an attacker to target the client's browser and/or computer. Theoretically they could steal the cookie from memory or disk out of the browser's space. It might be possible for a virus/trojan to do this or even a malicious browser extension. In short, if a user could get their hands on a valid, non-expired Forms Auth cookie, they could present it from any machine they wanted to until it expired. You can reduce the risk here by not allowing persistent auth cookies and keeping your timeouts to a minimum.
If they had the machineKey, they could create FormsAuth cookies from scratch whenever they wanted to.
Oh.. Can't forget Heartbleed. If you had a load balancer or reverse proxy that was using an insecure version of OpenSSL, it's possible an attacker could compromise your private key and intercept traffic over HTTPS connections. ASP.NET doesn't use OpenSSL, so you're safe from this in a pure-MS stack. If you ever hear anything about a vulnerability in MS' SSL implementation, you'd want to patch it ASAP and get your passwords changed and certificates re-issued.
If you are concerned about the browser/machine based hijacking, you might want to take a look at a project I started [and abandoned] called Sholo.Web.Security (https://github.com/scottt732/SholoWebSecurity). It's goal was to strengthen Forms Authentication by maintaining state on the server at the expense of some overhead on each request. You get the ability to do things like revoke tickets server-side (kick/logout a user) and prevent users from moving tickets between IP addresses. It can get annoying in the traveling mobile user scenario that Wiktor describes (it's optional). Feel free to fork it or submit pull requests.
The Anti-CSRF features that 0leg refers to apply to the UI/form mechanism that initiates the login process, but to my knowledge there is nothing in the Forms Authentication process itself that relates to CSRF. That is, once the cookie is issued to the client, the only thing protecting it from being bounced between servers is the fact that cookies are restricted to the domains/subdomain they were issued for. Your stackoverflow.com cookies won't be presented to serverfault.com. The browser takes care of that stuff for you.
Are there any ways to defend from that kind of attacks?
You shouldn't. Years ago we have had implemented such feature and abandoned it soon. It turned out that:
a single user making requests from the very same browser/machine but switching between http/https can sometimes be seen from different IP adresses
a single user traveling and using her mobile phone sometimes makes consecutive requests from different IP addresses when her phone switches between BTSes
Just to clarify the terminology, session hijacking is usually referred to the vulnerability where an unauthorized user accesses the session state on the server.
Authentication cookies are different from session cookies. ASP.NET puts a great deal more precautions in safeguarding authentication cookies. What you describe is better described by the term CSRF (Cross Site Request Forgery). As #Wiktor indicated in his response, restricting access by IP is not practical. Plus, if you read how CSRF works, the exploit can run in the user browser from the original IP address.
The good news is that ASP.NET MVC has built in support for CSRF prevention that is pretty easy to implement. Read here.

ASP.NET MVC 4 and session security leak

Instead of using ASP.NET MVC User's system, I'm simply using session, as the following:
When he logs in (username + password), I fetch the corresponding user from the Database and set:
Session["UserId"] = fetchedUser.UserId;
Then, I'm always checking if he is logged in:
if (Session["UserId"] != null && ...)
The problem is that if someone copies the value of ASP.NET_SessionId from a logged in user (eg: user goes to bathroom and coworker who is sitten next to him checks his cookies with chrome inspector), then he will be able to create a cookie in his computer and act as that user.
My questions are:
Why are sessions safer than cookies if the session id is saved in a cookie?
Can I make this safer (and continue using session)?
How does internally ASP.NET User authetication system do it?
A primary reason for not using Session as an authentication mechanism is that it could render your application vulnerable to Session Fixation. For example, a problem could be if a user arrived on your site using the HTTP protocol and receives a session ID that is stored in the ASP.NET_SessionId cookie. The user may later log in, and even though your login pages might be secured under HTTPS the session token has already been generated under HTTP which means it has already been transported using cleartext.
To answer your other points:
Why are sessions safer than cookies if the session id is saved in a
cookie?
The data stored in session is stored server side, so it is more difficult for an attacker to tamper with this data. All the cookie stores is a token for this data, rather than the data itself. Having said that, it is still safer to use the FormsAuthenticationProvider as this creates a new authentication token once login is complete rather than on session start for the reasons of avoiding session fixation as above.
Can I make this safer (and continue using session)? How does
internally ASP.NET User authetication system do it?
The built in provider is already fit for purpose, so it would be desirable to use that rather than fudge another mechanism to meet your requirements. It is also easily extensible so you can customise it to your needs. The ASP.NET User Authentication creates an encrypted ticket and stores it in the cookie rather than storing a reference to a server side variable: http://support.microsoft.com/kb/910443
I would also draw your attention to the signout mechanism and how to secure it. Particularly
Calling the SignOut method only removes the forms authentication cookie. The Web server does not store valid and expired authentication tickets for later comparison. This makes your site vulnerable to a replay attack if a malicious user obtains a valid forms authentication cookie.
Details here: http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.signout.aspx
In addition you may want to set the "secure" flag on your ASP auth cookie to prevent it being leaked over HTTP by a MITM attacker.

Regarding Session Hijacking & Protection in ASP.NET

i read few article about Session Hijacking. hacker sniff cookie and get the session id from there. but i think session id is stored in cookie as encrypted value. is not it?
is it possible to decrypt easily?
what other sensitive data is stored in session cookie...please explain. whatever we stored in session variable from server side code that is stored in session cookie...is it right?
please guide me regarding session cookie and what would be best way to protect Session hijacking. thanks
The idea is that they get the session cookie and used it as it is, to send it to the server and server connects the cookie with the victim session. Actually there is no data on session cookie, just an encrypted number of the session id.
Now there is a case that sensitive data stored on cookie and that is the Roles of the currenct user. To avoid a possible decrypt and change on web.config on <roleManager cacheRolesInCookie="false"
Also on the authentication cookie and on role manager always use the requireSSL="true", so its impossible to steal the cookie of authentication, but you must use secure pages for this make work.
How some can stole a critical session. This can be done if the programmer depends the critical data that show to the user, on the session id. For example, if you store the phone number and the name on a session variable and show that to the user, then some one can stole the full web page and read it (if not ssl). If you have connect the backoffice and the access to hidden administrate page with the session id, then if some steal the session cookie and open the pages, then he can gets on that administrators back office pages.
So its up to you not to store critical information's on session data, and always use ssl pages to administrate and to get send cookie critical data.
Now if a hacker steal the session cookie and you there just store what users see in previous pages, a history of products like amazon, then is not big deal because still can not connect this history with the user, but also can anyone sniff the urls that a user see.
Of course its up to you also to not store critical data on any unencrypted cookie !
So you split your data to critical ones, and not critical ones, and always use SSL for page and cookie for the critical ones, and never trust the data that comes from unsecure pages.
You can also read :
Can some hacker steal the cookie from a user and login with that name on a web site?
Hope this helps you.
An ASP.NET cookie stores Session ID and an Authorization Ticket; however, the issue is not whether one can decrypt the cookie, but rather to be able to create one with identical values and trick the server into believing that your copy of the original cookie is the real one.
The HTTP protocol is stateless so client and server don't maintain information about each other. Session Cookies (using the Session ID and Authorization Ticket) is how they keep track of each other. The web server knows which Session ID is attached to which authorization ticket and if you can provide a valid pair of these values, the web server will happily accept it. The Web server encrypts the cookie using a symmetric encryption algorithm and an autogenerated key (default setting). You can tweak these settings, if you want to, by modifying the appropriate sections in the machine.config file.

Resources