A java based application supports two user roles. Admin and nonAdmin.

Login as Admin ,browser gets JSESSION ID.

Login as nonAdmin user from another machine. Browser gets another JSESSION ID. Now edit this JSESSIONID and replace with Admin's JSESSION ID. This time a nonAdmin user get to see the options meant for admin user alone.

is this session fixation vulnerability? is it enough to bind other client side properties like IP address along with SESSION Ids? or setting new session id after successful login helps here?

  • This is not a session fixation vulnerability because from your described scenario it's not possible to impose a session ID on the victim. Copying the cookie manually doesn't count. – Arminius Sep 24 '16 at 18:41
  • If you give your keys to someone, they can get into your house. Don't give them your keys. – Neil McGuigan Sep 24 '16 at 22:39
  • They are not the same user. It is just an assumption that if admin's JSESSION id is stolen by some way like XSS. – renu Sep 25 '16 at 17:00

As @Arminus said in a comment, this is not session fixation. Session fixation is actually relatively rare today, because it relies on one behavior now (thankfully) widely recognized as insecure/stupid: when you log in, the server preserves the old token (JSESSIONID, in this case) rather than generating a new one. An attacker can abuse that by knowing the old token value (for example, because they were the last user) and then logging out and waiting for a new user to come along; when the new user logs in, they keep the old token.

A security vulnerability requires that somebody do something that they are not authorized to do. In your scenario, how the heck does the nonAdmin user find the Admin's JSESSIONID? If they're the same person, then the user is (presumably) already authorized to log in as an Admin - they did so on the other machine, after all - so no security bypass has occurred. If they aren't the same person, either the nonAdmin stole the Admin's JSESSIONID (in which case the security vulnerability is in how they stole it, which might be your fault or might be because the Admin user's computer has spyware), or the Admin user shared the JSESSIONID with the nonAdmin (which means the Admin is, essentially, deputizing the nonAdmin as a temporary user of the Admin's account).

Authentication tokens (JSESSIONIDs, in your case) have a number of critical properties. The following list is in no particular order. The relevant ones here are highlighted:

  • They are securely generated (i.e. don't use java.util.Random, which has predictable output; use java.security.SecureRandom). Some implementations use encrypted user-info strings instead of random tokens; this has some pretty bad security risks.
  • They are long enough that they can't be brute-forced (64 bits is generally seen as borderline; 128 bits and up is good).
  • They are never re-used, so an attacker who sees an old one can't use it to get somebody else's session. Since keeping track of all the old session tokens is infeasible, the solution is again to use a long-enough (random) token that the odds of a collision are infinitesimal (and if you express the odds against it happening using words like "billion", it's not infinitesimal enough).
  • They must be checked in a constant-time manner (otherwise brute-forcing a valid token becomes linear in its length, rather than exponential).
  • They must not be shared across privilege levels, or sessions for a given user. Any time a user re-authenticates, the old token must be invalidated and a new one used instead.
  • Token invalidation must occur on the server. If a user logs out or their session expires (or otherwise ends), the server must no longer recognize the token as valid. Simply deleting the token off the client is not sufficient.
  • Tokens must never be sent in a URL, only in headers or if necessary in message bodies. Even over HTTPS, URLs tend to leak (they may be recorded by proxies, included in referrer headers, or saved in browser history, among other risks). If a secure value absolutely must be sent in a URL, it must be single-use only and invalidated after the first attempt to use it, whether or not the user completed their action, and should also time out very quickly.
  • Tokens must never be sent over insecure connections. If your site supports HTTPS, then the token must never be sent over a non-HTTPS connection (an easy way to ensure this is have the token in a cookie, and set the secure flag on that cookie). If your site doesn't support HTTPS, then treat sessions as convenience only; there is no real security there. (Yes, looking at you, SE default post-authentication behavior...) I'm probably forgetting some, but a comprehensive list is not the core point here. Still, as you can see, there are a bunch of things (some related, some independent) required for a secure authentication token, which is just one component of a secure site. You have to do them all; one weak link is usually enough for an attacker to get in.
  • Great answer. Does the fifth bullet point essentially prevent imposing a session ID? – user124863 Sep 24 '16 at 20:46
  • 1
    @MattGalaxy: If you think of "before authenticating" and "after authenticating" as "across privilege levels" (rather than as completely different sessions, which I admit is a somewhat arbitrary boundary), then yes, the fifth point is also relevant. Some sites, such as Amazon, do in fact have an unauthenticated user session as well as an authenticated one, both tied to the same account (but you can't do sensitive stuff, like view order history or place an order, without the authenticated session. Note that Amazon retail is not a security paragon here...). I'll bold that point. – CBHacking Sep 24 '16 at 21:15
  • They are not the same user. It is just an assumption that if admin's JSESSION id is stolen by some way like XSS. – renu Sep 25 '16 at 16:56
  • If the token is stolen through XSS then you've already screwed up at least twice (once by having XSS, once by not making the token httponly-flagged), but I appreciate a desire for defense-in-depth. Generally, though, if somebody steals an authenticated session token and the user doesn't log out that session, that's it. Game over. You can do stuff like tie sessions to IP addresses, or prevent multiple sessions at once (whenever a user logs in, end any previous session that user had) but there are convenience costs to stuff like that. Best to just time-limit sessions (ON THE SERVER). – CBHacking Sep 26 '16 at 5:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.