More Secure than Yesterday - Keeping sessionid in the url - When did that became a Good ideea?
Now you may have heard that keeping the session id in the url is bad practice. Might even have read it in the previous post and I'm just going to reassure you it still holds true as long as you don't take other precautions.
A short full Recapitulation
Http Protocol is Stateless - Meaning you need to pass some sort of additional info into each request if you want the server to know that those requests are related(part of the same conversation if you want). This is where the sessionId comes into play most commonly used after the user logs in an used to identify requests corresponding to the same user. So by now you understand that you have big responsibility to not let this information fall into the wrong hands.
There are 2 most common possibilities for keeping the Session Ids:
- Either directly added into the URL
- Through a Cookie - since cookies are passed along with every request to the server-
- Session ids in the url might be passed by mistake through copy-paste to others. Without knowing the user has exposed his account and privacy to that person.
- Session ids may be leaked to 3rd party application through the Referer header or end up in server logs, Proxy logs
- URLs remain in the browser history
- Session ids passed through URL instead can be read by an XSS vulnerability (the URL on the other hand is readable through JS while an Http-Only cookie should be inaccessible to JS).
However the first approach of passing it into the URL has some bad reputation because:
But using JSESSIONID as a HttpOnly Cookie also has a big usability downside that if the user opens another tab with you application, all the tabs share the same session now since you just have one JSESSIONID Cookie that is common to all the tabs opening you application site.
Depending on the nature of your application that might be ok, but you may also want to keep them independent.
Storing the sessionid in a Cookie also had another downside in that without additional protection leaves you open to a possible CSRF attack.
Now think of the fact that the user wants to be logged into your application with different users in different tabs.
IDEAL: We'd want the user be able to use multiple sessionids into different tabs
Meaning we'd want the "jsessionid" in the url but we also need to make extra sure there is also something else required that prevents others who have the user's browser url from just using it to open his account. What is a low level of security is to have an additional check that the User-Agent value matches. The User-Agent as is pretty low probability of two users having the exact User-Agent.
Keep the User-Agent on the serverside on the session and recheck it's the same one stored. This should be ok itself but still remains the fact that through an XSS vulnerability in your site the User-Agent can be read through JS and passed to a malicious user along with the sessionid so they can fake it. We need to do better:
Better Solution - Take from both worlds!
Use the jsessionid in the URL +
1. Set a HttpOnly Cookie = Hash(UserAgent). Actually do =Hash(SALT + UserAgent) to prevent smart attackers from figuring what the algorithm is used to get the cookie value and reproducing that value from the known UserAgent.
2. On the server check that Hash(SALT + Session.getUserAgent()) = TokenCookie.getValue()
This means no longer can a 3rd party use just the url, also we've taken care of the XSS attack as even if an attacker gains knowledge of the User-Agent + sessionId it cannot reproduce the value of HttpOnly Cookie neither can he read it.
Bonus: The dynamic jsessionid in the URL acts as a token which also nullifies any possible CSRF attack(actually just by not using the cookie for the session solved that issue).
Till next time hope this info helps make the web a little more secure.
Thank you for reading.