Encrypting Only the Login Page
I occasionally hear people say that they don’t want to use SSL for anything other than the login page for fear of the performance hit that SSL adds. Most recently, I came upon this post which claims to show how to implement such functionality in a J2EE web application.
While the above post seems to have some technical inaccuracies, I’m not writing to criticize it. Rather, I think it’s interesting to consider the ramifications of only encrypting the login page. The issues fall into three categories:
- Security Impacts
Let’s have a look at each category in turn.
Performance is the crux of the reason to only encrypt the username and password. Developers hear that SSL adds a 30% overhead to response times, freak out, and then don’t want to use SSL or to only use it sparingly as this use case indicates. But really, the biggest hit of SSL is the initial setup of the socket. Once that is done, a big chunk of the SSL performance burden is gone. Since the socket is usually maintained until a timeout happens, multiple requests can leverage that same one-time setup cost.
Another thing to realize about SSL performance is that you don’t pay the overhead for your total response time. For example, assume that you have a dynamic page that takes 1 second to complete. Let’s further assume that 25% of that time is socket-level and 75% is making the database call and rendering the page. Clearly, I’m just fudging these numbers but you’re not going to see a 30% increase in the 650ms database access time, for example. By the same token, the more data you present (including images!) the more encryption has to be done which will take time.
Finally, a hardware SSL accelerator will go a long way toward reducing the SSL overhead. I don’t have any numbers for this but encryption in hardware will beat encryption in software any day.
While it doesn’t seem like this should be the case, encrypting only the login page introduces a software maintainability issue. Specifying that the login page should have a transport-guarantee of CONFIDENTIAL in web.xml will do the trick of ensuring that SSL is used for the login. No custom coding is required.
However, once the browser has switched to the SSL port, how do you declaratively tell it to go back to the clear (non-SSL) port after login? The answer is you can’t. Even though other resources defined in web.xml may not have the CONFIDENTIAL guarantee, the server will not automatically switch back to the clear port.
I can only think of two ways to switch back to the clear port — a servlet filter or links.
By using a servlet filter you could examine the request and then redirect to the clear port for anything other than the login page if the request was made over SSL. Do-able but not pretty.
The other way is to have all of your links specifically refer to the clear port with something like http://whatever/somepage.jsp. Clicking such a link will cause the request to be serviced without SSL but now you have hard-coded links all over the place. You could also build your link dynamically but then you’d have that code to maintain.
So far, we’ve talked about performance and maintainability. Now it’s time to consider the security aspects…
In this section you’ll see what that 30% SSL premium buys you.
It makes sense that you’d want to protect the user’s password and perhaps even the username itself. You wouldn’t want anyone sniffing the wire and finding those goodies. But by not encrypting the link post-login, all data sent or received from that user can be sniffed. You require authorization for the user to see the data but allow anyone with a packet sniffer to see social security numbers, medical conditions, or whatever sensitive data your application handles. Shouldn’t that be kept safe, too?
Perhaps you think you’re safe because you’re not going out over the internet. That is a good thing, of course, but the majority (80% is what sticks in my head) of attacks are from insiders. Kinda risky.
You’ve now seen that sensitive data can be sniffed from the link. Here’s where it gets really interesting…
You’ve encrypted the username and password during login so that no bad guys can login as that user in the future. But since subsequent traffic is unencrypted you’ve just given away the keys to the kingdom. How’s that? Session hijacking.
Now that traffic is unencrypted, someone sniffing the network can see session IDs either as a request parameter or in a cookie. Given this information and an active session on the server, the malicious use can become the previously authenticated user and access the application as if he were the legitimate user. Scary stuff…
I think you can tell by now what side of the fence I fall on. I think the security issues alone call for SSL during and after login. That 30% premium allows me to sleep at night.
Did I forget or overemphasize anything? Please post your thoughts below.