I am trying to implement security for my project that prevents session fixation.
As i have no access to the component (a filter from a certain library, lets call it MagicFilter) that handles the whole session-creation and validation, i was trying to find out another way of possibly doing it.
Now, consider this scenario for my session:
User requests the login-page
MagicFilter sets a cookie with a JSESSIONID etc
other filters do some work ...
Java Spring MVC, so as last step before the user sees the LoginView i have access to stuff in my LoginController. Here i .invalidate() the session right before i return the view.
So basically the user never has a real and valid session-ID while at the login-page. Only after he logs in the MagicFilter assigns another session-ID which will then be sticked to, as i only invalide() the session-ID in my LoginController.
But this feels very rough and i kind of had to "hack" around the automatic process of the MagicFilter.
Can anyone see if this should be safe in terms of session fixation or not?
Related
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.
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!
To counteract login session cookie theft, sniffing etc i've been thinking about this scheme.
i already read http://jaspan.com/improved_persistent_login_cookie_best_practice and what i wish to do is something less-complicated, maybe performance-wise faster too and something that blends well with both remember me functionality and normal session'ed login.
when registration is successful add session id to user(:uid) table and generate session cookie id for example d6c89ddba79b4f68be07bd874c5ff566 and store it in user browser.
When user visits another,the same page,refreshes it; another id will be generated and the current id in the user(:uid) table, the cookie in the user browser will be updated with the new one making the old one useless || invalid.
If an observer tries to steal the cookie, be it in unprotected connection, for example non-https website it will be rendered useless at user's next visit or refresh.
But... i'm sure there's a flaw somewhere in this logic. can the observer create a sort of time warping technique or do something locally to annihilate the benefits of such a scheme?
One concern comes to mind now.. i think it will be a possible situation that an observer steals the cookie when the user is afk or idle, then the observer refreshes the current page with that cookie or visits another one. the problem is that now the user is logged out while the observer has full grip of his account and can therefore change password if it's not a system where password change is confirmed through email or inserting current password before.
is that right? in that case, how could this scheme be enforced without bringing possibly extra complexity?
Yes, this is a good way to prevent session sharing:
the server will generate a new Session ID to store in the cookie every n number of requests. The Set-Cookie header will only be sent once, so if there are two browsers logged into the same session, one of them will be using the old, invalid session
is that right? in that case, how could this scheme be enforced without bringing possibly extra complexity?
As you say, you can get the user to confirm their password whenever a high security function is invoked such as password change. You could also get the system to confirm their password to continue the session in the case that session sharing is detected (i.e. some requests have been logged using the old session ID).
So I just read this article by Jeff Atwood and I wanted to make sure I understand it correctly as to how it applies to my use case. I am trying to validate a session for silent login. For security purposes this should be done with a POST right? Does it matter? I am just passing the sessionID and username from the cookie.
When it comes to CSRF (Cross-site request forgery), you can cause a user to take any action on any site which they are logged in to provided that the action requires only a GET. Forcing this to be done over a POST request defeats the approach of embedding an image, script tag, whatever in another page.
Even POST isn't completely secure in this scenario. There are other ways to mount a CSRF attack on a site using POST. Clickjacking/UI-Redressing enables another site to trick a user into submitting a form to a different website.
Basically the best way to validate is to add an automatically generated, hidden form element. You can store this inside your session data (Example: $_SESSION for PHP) so that you only need to generate a token at the start of a session. Of course, an attack could try do something like clickjacking (mentioned above) in combination with a iframe pointing directly to your site and possibly some JS to hide things a little.
For anything important you should re-prompt the user for their password, thereby greatly diminishing the value of any successful CSRF attacks.
I'm writing a GWT application where users login and interact with their profile. I understand that each form entry needs to be validated on the server, however, I am unsure about potential security issues once the user has logged in.
Let me explain. My application (the relevant parts) works as follows:
1 - user enters email/pass
2 - this info is sent back to the server, a DB is queried, passwords are checked (which are salted and hashed)
3. if the passwords match the profile associated w/ the email, this is considered success
Now I am unsure whether or not it is safe to pass the profile ID back to the client, which would then be used to query the DB for information relevant to the user to be displayed on the profile page.
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
-Nick
What you are dealing with here is a session management issue. Ideally, you want a way to keep track of logged in users (using random values as the session key), know how long they have been idle, be able to extend sessions as the user is using the site, and expire sessions.
Simply passing the profile ID to the client, and relying on it to send it back for each request is not sufficient - you are correct with your concern.
You want to keep a list of sessions with expiration times in a database. Every time an action is executed that needs user permissions (which should be pretty much everything), check to see if the session is still valid, if it is, extend it by however long you want. If it is expired, kill the session completely and log the user out.
You can store your session keys in a cookie (you have to trust the client at some point), but make sure they are non-deterministic and have a very large keyspace so it cannot be brute forced to get a valid session.
Since you're logging a user in, you must be using a backend that supports sessions (PHP, .Net, JAVA, etc), as Stefan H. said. That means that you shouldn't keep any ids on your client side, since a simple id substitution might grant me full access to another user's account (depending on what functionality you expose on your client, of course).
Any server request to get sensitive info (or for any admin actions) for the logged in user should look something like getMyCreditCard(), setMyCreditCard(), etc (note that no unique ids are passed in).
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
Stefan H is correct that you can solve this via session management if your session keys are unguessable and unfixable.
Another way to solve it is to use crypto-primitives to prevent tampering with the ID.
For example, you can store a private key on your server and use it to sign the profile ID. On subsequent requests, your server can trust the profile ID if it passes the signature check.
Rule 1 - Avoid cooking up your own security solution and use existing tested approaches.
Rule 2 - If your server side is java then you should be thinking along the lines of jsessionid. Spring Security will give you a good starting point to manage session ids with additional security features. There will be similar existing frameworks across php too (i did not see server side language tags in the question).
Rule 3 - With GWT you come across javascript based security issues with Google Team documents and suggests XSRF and XSS security prevention steps. Reference - https://developers.google.com/web-toolkit/articles/security_for_gwt_applications