Session Replay vs Session Fixation vs Session Hijacking - security

Can anyone give a clear difference between session fixation, session replay and session hijacking attacks? I have read many articles, but the matter is still unclear between session hijacking and session replay attacks.

Both fixation and hijacking have ultimately the same goal - gaining access to a session. They only differ in how you achieve that.
Session hijacking is simply the act of stealing an existing, valid session cookie. Most commonly through sniffing network traffic (a MITM attack), but also through any other ways that a session ID may be leaked.
Session fixation is similar, but inverted - a pre-defined session cookie is planted into the victim's browser. So after the victim logs into a website, they will use the same session cookie that the attacker already knows, and thus the attacker-owned cookie is now authenticated and can be exploited.
Of course that requires an attacker to have temporary access to the victim's browser itself, but the principle is very simple - there's no need to steal the data if it is under your control in the first place.
Replay is a bit different and can mean two things ...
If the attacker already has access to a session cookie (via fixation or hijacking), then it's just the act of reusing the cookie for whatever they want.
Otherwise, it can refer to tricking the victim into re-submitting a previously valid request (with the same session cookie). For example, a user could be tricked into buying multiple quantities of a good that they only wanted a single unit of.
Note: I've used "session cookie" everywhere to simplify the explanations, but of course there are other means of transferring session IDs.
How to protect yourself against these attacks:
Use TLS (HTTPS) to prevent MITM attacks and thus the most common ways of hijacking. Also set the Secure flag on cookies, to prevent them being submitted over a plain-text connecition (i.e. browsers will only send when using the https:// scheme).
Set the HTTPOnly flag on cookies, so that e.g. JavaScript doesn't have access to the cookie. If JS can't access cookies, that also means it can't leak them (can't be hijacked), but there's lots of other ways to exploit client-side code.
Regenerate session IDs on every privilege-changing action a user performs (login, logout, login as admin - if there's an extra form for that), as well as on regular, short time intervals. This serves as a mitigation mechanism against all of the 3 attacks.
Have your application reject session cookies that don't match a server-side record, to prevent fixation.

Related

Session authentication with cookie: security issue

I have a simple "session authentication" mechanism:
each time a user logs in a session it's created on database server side, and it's session id is set encrypted as a "session cookie" to the client
on logout or browser instance closing, the session is either deleted or invalidated
I've read and understood that by stealing a cookie encrypting the session id within an active session one steals another identity, and for this reason permanent cookie should not be used.
Still, even if i used a cookie with an short expiration date the theft can still happen within it. Are there other steps to avoid this problem?
It's legit to just use a short expiration date (if so, what is a decent time frame?), or are there other complementary technique to work around this problem?
The best practice for session cookies is to not set an expiry time so that they are valid for the browser session. If you set an expiry time, the cookie becomes persistent, will be stored on disk on the client and so on - it increases the overall risk.
You are right that anybody that has the cookie can impersonate the user. To avoid that, you want to have the cookie set as httpOnly to avoid Javascript access (XSS) and secure so that it is only sent over https.
While there are depths to correct session management, it doesn't seem to make a lot of sense to encrypt the session id. What is the purpose of that encryption? The session id should just be a large random number (possibly encoded into a shorter string, but still), there should be no need to encrypt it.
The generic advice around session management is to not implement it yourself. There are too many pitfalls, and pretty much all frameworks (or languages) have a solid implementation that you can just use reasonably securely. Avoiding all the potential vulnerabilities is hard.

If I don't send session ID by url do I need to cycle my session id on login

I've heard that my site can get attacked by hackers who:
Go to my site to start a session.
Somehow get a client to go to my site with the same session ID
The client logs in
When the attacker comes back to my site with the session id he has full access to that clients account.
I can see this being done if the session ID is passed by url and it makes sense to cycle it (session_regenerate_id) but is this needed if I just use session_start and I don't put the session id in url at any point in time?
There are session fixation attacks other than session-ID-in-URL. In particular, browser controls over cross-domain cookies are weak.
If an attacker has control over foo.example.com, for example by means of an XSS hole in an application running there, they can write a session ID cookie with parameter domain=example.com, which will then be passed to your application running at bar.example.com and hey presto session fixation.
As a developer you often don't have any control over what other vulnerable applications might be running in neighbour domains, so it is best to assume cookie injection can happen and recycle sessions on a princpal change.
Well, if the session ID is only transferd by a cookie (is not in the URL and you do not accept one in the URL) then it is not that important to protect against session fixation attacks by recycling the session ID.
However it is still good practice, as this could also help against a session cookie which was laying around longer time (and potentially be placed by a former user). So with most security practices it is the same here: just do it, even if you cant find a way it might get exploited.

Session Id placement: Form Hidden Field vs. HTTPOnly Cookie

What are the advantages and disadvantages of placing session id in a hidden form input vs a cookie?
Is it correct to put CSRF-Tag in a hidden form input field and session id in an httpOnly cookie? Which is more secure?
If you put Session ID in a hidden form field, that is a lot more secure, however it can hamper the user experience.
The reason is that is this would inherently protect you against CSRF because any cross-domain requests made to your site will mean that the browser will not automatically include the session identifier that makes CSRF attacks possible. It also neutralises session fixation attacks as there is no cookie to poison. Additionally any Login CSRF is also dead in the water.
To implement this, you would have every action on your site, including navigation, to be actioned via the POST method. The GET method would be unsuitable because this would expose the session identifier in the browser history, in any proxy or server logs by default, and can also be leaked via the referer header.
For example,
<form method="post" action="/executeAction">
<input type="hidden" name="sessionId" value="12345678901234567890" />
<input type="hidden" name="action" value="navigateToAccountStatus" />
</form>
Note that this will prevent use of the back button without the user re-submitting the form (which could be dangerous if the action wasn't a safe action). To guard against this, you could refresh the session identifier after each action is processed.
Another reason is this will protect your site against attacks such as POODLE. As there are no cookies for a Man-In-The-Middle to brute force one byte at a time from, a POODLE attack would be fruitless.
Note that this approach is more difficult to implement, and not many web-frameworks support it as default.
Is it correct to put CSRF-Tag in form hidden field and Session Id in httpOnly cookie?
Yes, this is the approach most sites take. It is "secure enough" for most purposes - only very high security systems like online banking should take the form approach.
I don't think that one is inherently less secure than the other. Security is generally built in layers. By asserting that choice A can be more secure than choice B, when both choices play on the same vertical, you are asserting that security stops there. This is completely false and unsubstantiated in practice.
By passing around session ids primarily in the form of hidden form inputs you actually create more problems than you solve for yourself. Also, I disagree with the assertion that this in anyway makes you inherently protected from CSRF.
When you think about what purpose a session serves (retaining state between the server and client over an otherwise stateless protocol), it doesn't actually make sense to say I will pass all of my session ids via hidden input fields. Because, for one, not every request made to your server involves the use of a form. For another, the state is lost the moment the user refreshes the page or closes their browser. This isn't pragmatic at all.
It is correct to place CSRF tokens in hidden inputs. It's also not incorrect to send them along to the client via HTTP headers. The CSRF token by itself isn't enough to prevent the attack. What's also needed is that the server understands how to recognize that this toke, which was supposedly uniquely generated for this client, is not reused and not tied to another session by the same user.
Since generally a CSRF attack is based on the premise that you cannot distinguish the real user from the malicious forgery, the idea is to make the forger's job more difficult by regenerating the token for every request. Coupled with a use-only-once requirement and it doesn't actually matter anymore that the session is hijacked. So you really shouldn't try to solve this problem at the wrong level, by assuming that you can somehow solve both problems by relying on passing your session ids in hidden inputs and convincing yourself that this is more secure than storing the session id in a cookie. It's not. There should be additional layers of security to protect your sessions from session hijacking or session fixation attacks like using SSL only cookies, HSTS, and regnerating session ids (while deleting the old session files) upon re-authentication requests. Also, forcing re-authentication for user-level non-idempotent actions.
But please please don't assume that hidden input makes you inherently more secure from CSRF or Session Fixation, or any of these attacks. It doesn't!

node user authentication with cookie

I am going to write a server api that responsible for user authentication. From my limit knowledge and understanding, when a user login with username and password, session will be created and auth cookie with username will save into cookie. When the user request for the next page, the user information in the cookie will send to server and server will recognize it. so my question is what if another person manually copy the existing cookie info and create the same cookie in a browser of another computer? Will it skip the login stage? Can anyone explain in details how to prevent this in details? thanks
Yes, it will most likely skip the login stage. What you describe is a form of session hijacking, or cookie hijacking. Using cookies over unencrypted connection (ie. HTTP instead of HTTPS) is not a secure solution because anyone can steal and use the same cookie and this is usually enough to get full access with no need to authenticate. (It can be - though it usually isn't - made harder to exploit but not impossible.)
Soon there will be no reason not to use HTTPS (see my answer to other question for details).
In addition to making sure that no one can read the cookie (using HTTPS and HttpOnly) you also have to make sure that no one can guess the session ID (eg. it cannot be a sequential or small number or anything like that).
See also:
Session hijacking on Wikipedia
Session hijacking on OWASP
Session fixation on Wikipedia
Session fixation on OWASP
Session riding (XSRF, CSRF)

Session fixation with session in cookies

There are a lot of questions and answers about session fixation on StackOverflow, however, I am still confused about one thing. People often suggest that storing session in cookies is not enough to overcome the session fixation issue and you should rotate the session id after login. I can imagine that if you only use the session id to identify a user, you may still be vulnerable to an attack. However, I would like to ask about one specific case.
Let's assume that you use a signed cookie to store the whole session. On login you put into the cookie an id identifying the user. After logout, you delete the id. You do not change the session id, but as you change the session itself and you sign it, I cannot see any attack scenario taking advantage of this design. Is session fixation still an issue and, hence, is session id rotation still necessary in this case? If yes, can you provide an attack that could be used? Thank you.
The basics of Session Fixation is that it’s possible for an attacker to make the victim use a session that the attacker has access to. This is generally done by inducing the victim to use a certain session ID that is known to the attacker and doesn’t change after authentication.
Now what you’ve described doesn’t sound like a session identifier but rather a simple client-side data storage of user authentication data.
But nonetheless, if you make the cookie data dependent on data that again depends on the authenticated user which additionally is signed by the server, it certainly will change after authentication and won’t be known to the attacker. Then the security of that scheme depends on its actual implementation.

Resources