First, I assume you understand the most basic session ID security right:
- you are using an ID with sufficient entropy, and
- you use transport level security (HTTPS).
Any approach to session ID (URL, cookies, whatever) that does not get those right is vulnerable, your question is specifically about ID in URL, so I will not discuss that further.
The most obvious risk of ID leak is with the
Referer HTTP header. The simple solution to this is either:
- to forbid outgoing all links (
<a href and others), all external embedded content (
<object>...) and other external dependencies (
- to change all outgoing links to go to an internal redirection page (which could be another security issue, depending on how you implement this).
Many Web application have zero outgoing links, and no content (esp. HTTP resources) from other users (which often has potential security/privacy issues, like Web bugs in emails).
This issue is usually described as a serious risk, but I disagree; if well understood it is easily managed.
User-behaviour related leaks
Voluntary sharing of URL with other users
Another practical issue is that users could fail to recognise the URL as the access key to the page, and share it with others, via email or in a forum. The risk is even higher if the document is public but the user might have some privileged access to it (like in SE), so sending the URL is the most obvious things to do to share a page with a friend.
When the page is by nature private and contains sensitive personal informations, such as the interface to manage your account, the risk is lower, but still exits.
I have personally witness more than one case of non-public URL being posted on a public forum, where the URL designates a web page random users could not ever legitimately access:
- link apparently to a webmail: the link was not working, I presume because the session was cookies based and not URL based;
- link to the configuration page of a modem-box in the administration Web application of the ISP; the administration application is on a public Web server and requires authentication (this allows ISP clients to view or change some of their account information from anywhere). Giving others access to this interface includes: giving bank account information, ability change account password, change account email contact address, buy optional features, terminate account ... or just click the "disconnect" button to terminate the session.
The issue I am pointing out here is not the web application design, but that the behaviour of a few uneducated users is to copy URL and post it even when the account manages some serious stuff (not just a lame forum account).
In the second example, it clearly shows that some user simply to not think about what they are doing: the shared URL was either useless for people willing to help, or a security risk. This is just simple logic, and zero technical knowledge was necessary to understand that: either an information is sufficient to access some other information, or it is not, so obviously this link was useless or a serious risk.
Usually when such URL is posted in a public place, some nice guy sees the URL, copies it and if the session is still valid, clicks "disconnect"; then he explains that serious issue to the user. Most people are honest, but there is a risk.
Sharing of screen shots (revealing URL)
Another risk is when users want to share some data shown on one administrative web page (and not their access to such page), so they make screen shots of an administrative web page, failing to realise that the cryptic information in the URL bar is a secret. Making the URL very long so that it is not visible on user screen lowers this risk.
This case is very different, as the sharing of information is voluntary but the fact is contains the URL is not realised by the user.
Technical and user issues
Some technical issues exist with ID in URL; other issues exist with ID in HTTP cookies. In both cases it is up to the developer to understand the issues and fix them.
A user expectations issue exists with the "secret in URL" approach. The issue is not that the user can see the secret information, it is the fact the URL bar does not usually contain a secret.
You could think of a social engineering attack were the user is convinced to install the (very nice) Firebug plug-in, then activate it, go to the cookie panel and copy session cookies from there. But even a user willing to do everything you tell him might not be able to correctly accomplish each of these steps!
Copying the content of the URL is not just very easy (downloading malware on the Web and installing is easy enough for many users too); the user is used to copy and send URL. Some more experienced user may have explained a beginner how to send a link to a news article. The beginner might assume he can do that on any website and any webapp (even if the more experienced user never told him anything like that).
The problem here is that you can review your webapp design, you can get help from security experts and pay them to do a complete analysis of your application (complete from design to every line of code), but you cannot do a security analysis of your users (unless this webapp is only intended for your highly qualified employees and security consultants).
You could combine both ID in cookies and ID in URL, if:
- both ID are different, independent cryptographic random numbers
- and each ID contains sufficient entropy for secure protection if the other ID is leaked.