« TLS Server Name Indication now in Apache | Main | Black Hat 2009 SSL Review: Black Ops of PKI (Dan Kaminsky) »

Improved SSLv2 detection in SSL Labs

August 03, 2009

Update (5 Sep 2012) Someone wrote to me recently to point out that accepting SSL v2 connection requests is insecure, even if the intention is to only display an error message. This is, of course, correct. I come to the same conclusion long time ago, but I had forgotten that I had left behind a written trail in favour of this technique.

One of the benefits of public testing is that you get exposed to, well, real life. I love that phase of development because you generally get to polish your code until it is perfect. Thus, after my SSL server assessment service went online, I monitored its performance closely, expecting to encounter a number of unforeseen cases, or cases that I didn't handle well.

One such area was SSLv2 detection. My first approach was to simply detect the cases where servers accept to negotiate a SSLv2 connection, but I soon discovered two edge cases:

  1. Some servers have SSLv2 enabled, but all of the SSLv2 cipher suites disabled. Technically, although they support SSLv2, it is impossible for the handshake to complete, which has the same end result as protocol disablement.

  2. Some servers accept SSLv2, but they always respond with a special error message to all requests. This is actually a very good idea from the usability point of view. An SSLv2 user connecting to a server that does not support SSLv2 is only likely to get a cryptic error message from their browser, which may leave him wondering what to do. Accepting a connection, only to deliver a user-friendly error message is a very good idea.

Now, dealing with the first case is easy: you just keep a would-be SSLv2 connection open for a bit longer. A failure to negotiate a cipher suite means SSLv2 connections are effectively impossible.

Handling the second case is difficult because there is no standard way to deliver user-friendly protocol errors. For example, this is what Amazon gives you (I suspect the error page is delivered by the load balancer, although it's perfectly possible to implement it on the application level):

HTTP/1.1 500 Internal Server Error
Connection: close
Content-Length: 309
Content-Type: text/html

<html><body><b>SSL Protocol Alert</b><p>The SSL protocol version that your
browser uses is SSLv2 and it is not compatible with the server settings.
</p><p>Please try the following:</p><p>- Check the SSL protocol settings
on your browser for SSLv3/TLSv1 protocol support and enable the same.

Amazon is kind enough to indicate that there is a problem by setting the response code to 500, which is easy to detect. Adding a check for this special case was easy. In a general case, however, I can't just assume that everyone is going to do the right thing. I know they won't. So, for the time being, I am logging all unusual responses to requests over SSLv2 connections. In time I plan to automate the detection by observing if the tested site "looks" substantially different over SSLv2 (not sure what exactly that means, but I will figure it out).

Thanks to Bo and Brandon, who emailed me to discuss the above two issues.