Harm of passing session id as url parameter - security

So I just noticed that one of the internet banks websites is passing session id as url parameter. ( See image below )
I didn't previously see anywhere that ';' in url, in this case it is after 'private;'.
1) What is the use of this ';'?
2) And why internet bank, which needs to be securest place in the internet is passing session id as url parameter?
At first, I thought they are doing it because some of the users disallow use of cookies, but then again, if they allow it, use cookies, if not - url, but I do allow use of cookies, so obviously thats not the case.
3) I guess then they should have some other security measures? What they could be?
4) And what one can possibly do if he knows others valid session id?
As I know, you can quite easily log into others peoples session if you know that id, because its not hard to edit cookies and its much easier to pass that session id as url parameter, especially if you have something like:
session_id($_GET[sessionid]);
Thanks!

1) You should ask whoever designed the application your red box is covering. URL can be anything you want; the convention of key=value&key2=value2 is just that - a convention. In this case, it's Java, and it commonly uses the convention of ;jsessionid=.... for its SID.
2) It's not that big of a deal. Normal users can't copy-paste cookies like they can copy-paste a GET parameter, but power users can do whatever they want (using Mechanize, wget, curl and other non-browser means, or even browser extensions). And if you allow it for some users and disallow for some, it's not really much of a security precaution, is it? Basically, cookie SID will make the attack a bit harder, but it's like putting your front door key under the mat - definitely doesn't keep your door secure. Additionally, cookies are shared between tabs: if a site wants you to be logged in with two accounts at once, you can't do it with cookies.
3) Serverside security, yes. One effective countermeasure is one-time SIDs (each time you visit a page, the server reads the session from the current SID, then starts a new session with a new SID for the next request). A less effective but still good method is to validate other information for consistency (e.g. - still same IP? Still same browser?)
4) Yes, if you know someone's valid SID, and the server does not adequately protect against session fixation, you can "become" that person. This might enable the attacker to, say, pay his bills with your money, for instance.

So, #Amadan correctly covered #1 and #4. But there's a bit more that needs expansion.
Using Session identifiers in a URL can be a major problem. There are a few cases where it's critically bad:
Session Hijacking:
If a user copy-pastes a URL into an email.
In this case, the attacker can simply read the email, and steal the session identifier (thereby resuming the session).
You could partially defend against this by making session lifetimes short, and validating things like IP addresses or User Agents in the session. Note that none of these are foolproof, they just make it "slightly" harder to attack.
If the connection is ever downgraded to HTTP.
If they are not using Http-Strict-Transport-Security (HSTS), then an attacker may be able to successfully downgrade the session to HTTP only (via MITM style attack). If the server isn't setup perfectly, this can cause the URL to leak to the attacker, and hence the session identifier.
Session Fixation Attacks
An attacker can craft a session identifier, and send the user a forged link with that session identifier. The user then logs in to the site, and the session is now tied to their account.
You can mitigate this by strictly rotating session identifiers every time the session changes (log in, log out, privilege upgrade or downgrade, etc). But many servers don't do this, and hence are susceptible to fixation style attacks.
The reason that cookie sessions are seen as more secure is not because they are harder to edit. It's because they are more resistant to fixation attacks (you can't create a URL or link or form or js or anything that sends a fraudulent cookie on behalf of the user).
Why the bank uses a URL parameter? I have two guesses:
Because they want to support those who don't allow cookies.
Which is sigh worthy.
They don't know any better.
Seriously. If it's not in a compliance doc or NIST recommendation, then they likely don't do it. Hell, there are implemented NIST recommendations that are known to be insecure, yet are still followed because it's in writing.

What is the use of this ;?
This is just a query string separator. & isn't the only sub-delim specified in the URL specification (RFC 3986).
And why internet bank, which needs to be securest place in the internet is passing session id as url parameter?
It could be that this session ID is never used, and the actual session identifier user is passed in cookies or in POST data between each navigated page. The only way to verify this is to try copying the URL into another browser to see if your session is resumed, however then again they may be checking things like User Agent - not real security but would dissuade casual attacks. Do not try this on a live system you do not have permission to do so on as it would be illegal. If you want to learn about security download something like Hacme Bank and try on there.
I guess then they should have some other security measures? What they could be?
No doubt they will, otherwise this would be a huge security threat. The URL could be leaked in the referer header if there are any external links on the page. The types of security a bank uses for their website is too large to list here, however they should be meeting certain industry standards such as ISO/IEC 27001 that will cover the types of threat that their site would need to be secure against.
And what one can possibly do if he knows others valid session id? As I know, you can quite easily log into others peoples session if you know that id, because its not hard to edit cookies and its much easier to pass that session id as url parameter, especially if you have something like:
As the ID is displayed on the screen it might be possible to read it (although IDs are generally long). A more realistic attack is Session Fixation. This is where an attacker can set the Session ID of their victim. For example, sending them a link that includes the attacker's Session ID. When the victim follows it and then logs in, as the attacker has the same session, they are logged in too.

Storing the Session information in a cookie or in a URL are both viable methods. A combination may used as
Security session management and (Server) Session management are separate aspects:
The fundamental difference is that cookies are shared between browser windows/tabs, the url not.
If you want your user to be logged on when navigating to the same site in different tab, sharing the security session (=without a new logon procedure) then cookies are a good way.
To differentiate "sessions" per tab and associate distinct server sessions with distinct tabs (Think of the user running two "stateful" transactions in two different tabs in parallel), managing a sessionId on the client which can be different per tab is required. Cookies won't work here.
Putting it in the URL is one way to assure this information is routinely added to requests fired from the page (referrer header). Alternative methods would require specific code to add this information explicitly to each request which is more work.
See How to differ sessions in browser-tabs?

Related

How secure are sessions?

From what I understand and have read about sessions, a website, like Facebook, will store a code on your computer that your computer sends back to Facebook every time you visit their site. This saves you the trouble of logging in every time you want to see your news feed.
My question is, how is this in any way secure? Can't anyone write a simple program to find this code on your computer - just like Facebook does? Or if you let your geeky friend use your computer, how do you know he doesn't copy your session codes and just use your account from somewhere else?
I read that sessions are more secure than cookies because cookies actually carry information like your username, password and other vital info. But if a session code can provide access to your whole account anyway, isn't a session just as insecure?
Are there any other factors at play that I don't know about or are sessions really this insecure?
My question is, how is this in any way secure? Can't anyone write a simple program to find this code on your computer - just like Facebook does?
Yes. Someone can do that. And they can steal your session credentials. If your computer is compromised, you can't build any form of security on top of that. If you can't trust the computer, you can't trust the browser. And if you can't trust the browser, there's no way you can possibly trust the website.
So we need to start with a fundamental assumption. To secure the website, we must assume the browser (and hence the computer) is secure.
If you can get code onto the computer to search for the session identifiers, it's game over already, since you can typically do much worse while you're there.
Or if you let your geeky friend use your computer, how do you know he doesn't copy your session codes and just use your account from somewhere else?
You don't. This is why you shouldn't let friends use your computer (among other reasons).
There are some techniques that can be done to verify the session came from the specific computer. But they tend to be either insecure (like verifying user agents) or fragile (like verifying IP addresses).
I read that sessions are more secure than cookies because cookies actually carry information like your username, password and other vital info. But if a session code can provide access to your whole account anyway, isn't a session just as insecure?
Sessions are no more secure than cookies, because the session uses a cookie for identification. Sure, the specific data doesn't leave the server (so it doesn't leak), but the attacker can resume the session.
Are there any other factors at play that I don't know about or are sessions really this insecure?
The key here is who are you trying to protect against. Specifically, what threat model:
A friend, who you give admin access to your computer (let them borrow with a privileged account)
You can't reliably protect against that. If your users let others borrow their computer, you, as a website operator, can't help that unless you don't use a session at all and require users to authenticate every action.
Simply don't do it, or give them a clean guest account. Or better yet, use a chromebook, and let them sign in with their own account.
An attacker getting code onto the computer
You can't help that.
Someone snooping the network traffic (read-only) like a network packet sniffer.
Use TLS (HTTPS)
Someone man-in-the-middle attacking the network traffic (read/write)
Use TLS (HTTPS)
Someone attacking the server
Secure your server!!!
In general, to figure out how to secure something, you need to consider the vector the attack is going to come from. Some attacks you simply can't defend against. And some, you just need to educate the user about.
Session IDs are stored in cookies, so their security is the same as that of cookies.
Cookies are handled by your browser, which takes care of protecting them to the extent that it's possible.
No website can "ask your browser for a cookie" (and that is not what Facebook does). Instead, when accessing facebook.com, your browser sends along your facebook.com cookies, but not your google.com cookies.
Of course, "writing a simple program to find this code" would be easy, but distributing it wouldn't be that easy (i.e. you're talking about distributing malware), and it's definitely not what Facebook does to get access to the relevant session cookies.
There are several additional ways to protect cookies from unauthorized access (to a certain extent). One of them is to make them "HTTP-only", so that they aren't accessible in Javascript (they'll still be sent to Facebook's servers, but the browser won't expose them to anything else).
Note that cookies are indeed as secure as the browser itself. If your browser is "compromised" (by your geeky friend), then so are your cookies, and so is your session.

What, exactly, are the security concerns with sending session tokens in the URL?

I'm building a Flex client against a Struts backend and I have to find a way to transmit the session token without relying on cookies, because I can't use cookies in a Flash movie.
I'm looking at putting the token in either the message body or the URL. Putting it in the URL has somewhat of a bad reputation, security-wise. However, I just read up on session hijacking, CSRF and XSS, and I couldn't really see why it should be worse than cookies. If anything, not having a cookie that is transparently sent along whenever you access a particular domain is more secure, or is it?
Basically, the only reason I can see is that the token is visible in the request and might be leaked via the browser history, a web server log etc. How bad is this really, and are there ways to mitigate risks? What other risks might there be?
How bad is this? Well, one of our competitors had a link from their internal (session based pages) to our site and I saw it on the server logs. Quick copy and paste with the /sess/sess_34984923_34423423/ type stuff and I was logged into their system with full access permissions of that user (luckily, they weren't an administrator and it wasn't anything "super secure" like a bank/email etc: but still).
Also, depending on how exactly you implement it, the full url (including the session token) could be cache by proxy servers and even by Google (if people use the Google toolbar).
The way I've done this Flash session interactivity is to send a session identifier in the Flash parameters (in the HTML) to the Flash which then sends it back to the server. I've found most browsers/Flash combinations also send the cookie which I further authenticate against.
I have an anecdote for you. I was filling out some paperwork for a well known company in the US. They printed out a confrontation page generated by a web application, how do I know? At the bottom of the page Window's print manager included the URL which had the JSSESSIONID.
Let me be clear, the employee just handed me a sheet of paper that would allow me to login immediately as if I had their username and password. DOAH!
I suggest you further read on a very severe security topic called Session Hijacking which allows a malicious attacker to impersonate to a user once he have his session id.

What's the accepted techniques for staying logged on to a web site?

Most web sites you can log on to also provide the feature so it remembers you between sessions.
What's the accepted and secure techniques for implementing that ? (What do you put in the cookies and how do you handle it on the server/db?)
This recent 2009 chapter in Spring Security 3.0 discusses Remember-Me type authentication. The general concepts are not specific to Spring Security so you should be able to benefit from it even if you are not using it. The chapter also cites a Barry Jaspan's 2006 blog posting which is an improvement over the techniques described in Charles Miller's 2004 blog posting.
The blog entry basically comes down to:
When the user successfully logs in with Remember Me checked, a login cookie is issued in addition to the standard session management cookie.
The login cookie contains the user's username, a series identifier, and a token. The series and token are unguessable random numbers from a suitably large space. All three are stored together in a database table.
When a non-logged-in user visits the site and presents a login cookie, the username, series, and token are looked up in the database.
If the triplet is present, the user is considered authenticated. The used token is removed from the database. A new token is generated, stored in database with the username and the same series identifier, and a new login cookie containing all three is issued to the user.
If the username and series are present but the token does not match, a theft is assumed. The user receives a strongly worded warning and all of the user's remembered sessions are deleted.
If the username and series are not present, the login cookie is ignored.
Signed cookies that can not be tampered with can be a good idea when you don't require a whole server-side state ... lean mean and efficient.
You still run the risk of cookie theft but you can always sign the cookie using IP address, User-agent and other things to help minimize the threat.
It's just a cookie with a long life value assigned. However it will only work so long as the cookie exists. For example, I have my Firefox set to clear my cookies when I close the browser. So this wouldn't work for me.
Cookies, but the user can decide to delete it.
In the same spirit there is some kind of solution, using Flash. Flash can store informations on the client-side, not a cookie, it's not erased (usually) by the browser. With it, you can remeber which user is asking for pages, but you're stuck using a plugin-using solution, and need to know Flash..
I don't see any other solutions.
Do not try to implement session cookies yourself.
Most web frameworks give you an abstraction over this, leaving you care-free about the many security issues you might be exposing yourself to.
A simple API in pseudo-code in a web framework might look something like this, on login:
authFrwk.loginUser(request.POST.get(username), request.POST.get(password));
This will return a cookie to the client (handled exclusively by the framework).
A securely authorized operation will look something like this:
if (authFrwk.isLoggedOn()) // implicitly checks user session cookie
doSomethingImportant();
else
return notLoggedInMsg();
Basically, a session cookie is given a unique ID on the server-side, which a malacious user cannot generate/guess by himself, and which identifies the client as a logged-on user.

Securely implementing session state and 'keep me logged in' feature

I would like to improve security on a current application regarding session management and I want the users to be logged in until they explicitly logout.
How does one implement that securely?
Keep session information in database, like sessionid, ip, useragent?
Please provide the requirements, possibly a database layout, do's and don'ts, tips and tricks.
Note:
I know frameworks like asp.NET, rails, codeigniter, etc... already take care of that, but this is not an option. Actually it for a classic asp application. But I think this question does not relate to a specific language.
Read Improved Persistent Login Cookie Best Practice (both the article and comments).
You should know that such a system cannot be secure unless you use https.
It's quite simple:
User logs in.
The server sends the user a cookie with an expire date far in the future.
If you want, you can record the IP of the user.
User requests another page.
The server checks the cookie (possibly the IP stored with the cookie), sees that the user is logged in, and servers the page.
Some security considerations:
As stated above, there is no secure way unless you use https.
If you're using shared hosting, try to find out where your cookies are stored. Often they reside in the /tmp directory, where every user as access to and through that someone could possibly steal your cookies.
Track the IP, if you know that the computer isn't ever going to change it.
Don't store any information in the cookie. Just store a random number there and store the information belonging to it on the server in a database. (Not sensitive information like preferred colour can be stored in the cookie, of course.)
Create a cookie with a ridiculous expiry like 2030 or something. If you need session state, keep a session ID in the cookie (encrypted if security is priority) and map that to a table in a database. IP/UserAgent etc. tend to be meta-data, the cookie is the key to the session.

Exists a way to prevent cookies from getting stolen?

in Web 2.0 applications many users usually want to stay logged in ('remember me' flag) and on the other hand their cookie can give access to very private data. Is there a way to prevent that somebody who steals the cookie - directly from the computer or via sniffing - can use the cookie to get access to the user's data? Always HTTPS is not an option.
Thanks, Bernd
[Edit] Connect the IP address to the cookie is not an option either.
KISS -- just use sessions so that you're using an ID that is already automatically created by the server-side scripting language of your choice. That's hard enough to guess. Then, if it's stolen, store the IP address and user-agent of the visitor in the session (making sure never to output that) and only consider the session valid only if the already stored IP address and user agent match that which is found for the remote client.
In this scenario, the attacker would have to do the following three things:
Steal the victim's cookies
Spoof the correct IP address
Spoof the correct User Agent
It also helps to make sure that the attacker doesn't already know all of the things he/she would have to do in order to correctly take over a victim's session. IE: They may assume just the cookie is needed and then fail... and have to figure out everything else through a very long trial and error. In this way, you gain security through obscurity and through difficulty, depending on the skill of the attacker and his/her existing knowledge of the system.
Bernd -- the trouble with anything done over standard HTTP is that it's plaintext; anyone can fake anything. IP Spoofing is a bit more challenging to do than just plain cookie stealing, so tying to the IP tends to be what people do. Like you said, that does not work very well with highly dynamic environments.
The only mostly secure way I can think of is to use HTTPS to place and verify a "permanent" cookie, and then place (in the same HTTPS session) a short-lived session cookie. The rest of the communication can be done over regular HTTP, using the session cookie to authenticate.
That way, fewer resources are used in supporting encryption (just the handshake), the permanent cookie is not exposed -- it's only transmitted under encryption -- and stealing the session cookie opens up to only limited risk, since that cookie will quickly expire.
All that being said -- don't let users click "remember me" on a site that contains truly sensitive data! That's why Banks don't do it..
Hope this helps.
About storing complex cookie ids and associated IPs in a database -- you don't really have to do that. If you have a secret key K, it is enough to encrypt the user's ip with your K, and place the result {IP}K as a cookie. As long as your key is secure (and the crypto hasn't been broken -- but if that happens, we have bigger problems), this is safe.
Perhaps using a Session ID and token (a hash based on the IP, a salt, and the Session ID), that is regenerated every request (use a fast hashing algorithm) would be a good approach? I store session data in a database (currently), and this means I have a two query overhead every request. It works like this:
Select where SID and TOK match.
Verify a token generated based on current client matches that in the database.
deserialise the data into a property.
Scripts etc happening.
Serialise the updated data, regenerate the SID/TOK, and update DB where SID/TOK = old sid and tok, updated data and new sid and tok. Set the cookie to the new SID and TOK.
In this way, firstly cookies are bound to whatever I base the token on (in this case, remote address), and if that is stolen and client data spoofed, the cookie is only useful for one request anyway - by the time the cookie is intercepted, it is useless.
The only perceivable weakness I can see is if the attacker managed to grab a cookie, spoof, and use it, before the real person could do another request. There are a few ways to solve this that I need to think about. The overhead is two queries and generating a token hash twice (once for verification, once for replacement).
Put a lid on the cookie jar.
Jokes aside, the best option has already been stated - make the cookie an obscure ID and tie it to an IP address lookup on the server side. Since you edited to say you cannot tie it to an IP address, that leaves the obscure ID part. Your options are limited with cookies - the minute you place something on the client, it becomes a risk.
Store a cookie that is an obscure ID into your local server database. Do a server-side DB lookup based on the ID provided in the cookie. Be sure to make the ID sufficiently complex that it cannot be easily guessed. Map the ID to the IP Address of the user. If their IP changes, then force them to log in again, and create a new ID.
On second read, it sounds like you want a high level of security with your hands tied. The user must have the choice to remain logged in and thus increase his/her risk. You can implement all the security in the world from the application's and server's point of view, but if the user forgets their laptop on a table in Tim Horton's (Canadian Starbucks), then none of it will do you any good.
Leave the choice up to the user as to whether or not they remain logged in, and give them a warning about their information being at risk.
Bernd - you say connecting the IP address to the cookie is not an option, I'm assuming that's b/c the user could be connected via DHCP, and thus could come in under a different IP each time. Have you considered tying the cookie to the DNS host name? You could encrypt the cookie using a private key, and store it on the user's box. Then whenever they come in, check the cookie, un-encrypt it, and then check the user's current DNS Host name against the one in the cookie. If it matches, you allow them in. If not, you don't allow the auto-login.
FYI - in ASP.Net, to get the DNS host name of the user's box, just look at
Page.Request.UserHostName

Resources