HAProxy and sslv3 poodle vulnerability

SSLv3 poodle vulnerability

Yesterday, Google security researchers have disclosed a new vulnerability on SSL protocol.
Fortunately, this vulnerability is only on an old version of the SSL protocol: SSLv3 (15 years old protocol).
An attacker can force a browser to downgrade the protocol version used to cipher traffic to SSLv3 in order to exploit the POODLE vulnerability and access to data in clear.

Some reading about SSLv3 Poodle vulnerability:
* http://googleonlinesecurity.blogspot.fr/2014/10/this-poodle-bites-exploiting-ssl-30.html
* https://www.imperialviolet.org/2014/10/14/poodle.html
* https://www.poodletest.com/

Today’s article is going to explain how to use HAProxy to simply prevent using SSLv3 or to prevent those users to reach your applications and print them a message.

Disable SSLv3 in HAProxy

In SSL offloading mode

In this mode, HAProxy is the SSL endpoint of the connection.
It’s a simple keyword on the frontend bind directive:

  bind 10.0.0.1:443 ssl crt /pat/to/cert.pem no-sslv3

In SSL forward mode


In this mode, HAProxy forwards the SSL traffic to the server without deciphering it.
We must setup an ACL to match the SSL protocol version, then we can refuse the connection. This must be added in a **frontend** section:

  bind 10.0.0.1:443
  tcp-request inspect-delay 2s
  acl sslv3 req.ssl_ver 3
  tcp-request content reject if sslv3

Communicate a message to users

Denying sslv3 is a good way, but a better one would to educate as well users who are using this protocol.
The configuration below shows how to redirect a user to a specific page when they want to use your application over an SSLv3 connection. Of course, HAProxy must allow itself SSLv3:

frontend ft_www
  bind 10.0.0.1:443 ssl crt /pat/to/cert.pem
  acl sslv3 ssl_fc_protocol SSLv3
# first rule after all your 'http-request deny' and
# before all the redirect, rewrite, etc....
  http-request allow if sslv3
[...]
# first content switching rule
  use_backend bk_sslv3 if sslv3

backend bk_sslv3
  mode http
  errorfile 503 /etc/haproxy/pages/sslv3.http

And the content of the file /etc/haproxy/pages/sslv3.http:

HTTP/1.0 200 OK
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<head>
<title>SSLv3 spotted</title>
</head>
<body><h1>SSLv3 spotted</h1></body>
SSLv3 forbidden for your safety:<BR>
http://googleonlinesecurity.blogspot.fr/2014/10/this-poodle-bites-exploiting-ssl-30.html<BR>
<BR>
If you want to browse this website, you should upgrade your browser.
</html>

Links

10 thoughts on “HAProxy and sslv3 poodle vulnerability”

  1. Serving a static error page on SSLv3 connections seems nifty, but doesn’t this make the whole point of disable SSLv3 mood?

    Let’s assume the most common attack vector for POODLE: Given Alice with an existing and valid session cookie, communicating over TLS. To get this cookie, Mallory performs a protocol downgrade attack, forcing Alice to fall-back to SSLv3 followed by the probing for a session cookie. Now, if your server doesn’t speak SSLv3 at all, the attack will fail as no Layer 7 information will be pushed to the server. If the server however speaks SSLv3, the client will happily send the session cookie over.

    At this point, it doesn’t matter that the requests don’t actually arrive at the backend app because Mallory is only interested in validating the cookie sent by Alice. And for that, the HTTP response doesn’t matter at all, it is enough if the spoofed SSL packages are accepted by the server.

    Thus, unless I’m completely misguided (which is very well possible), the only working mitigation for POODLE is to actually disable SSLv3. The approach presented here although really nifty will not fix the issue.

    1. Hi Holger

      You’re right but you’re assuming that Alice must have an existing and valid cookie which has not expired yet…

      Note that HAProxy is so flexible that I could also update the article with a configuration that manages a black list of cookies in a stick table. Blacklisted cookies would be the ones presented over an SSLv3 connection.

      Baptiste

      1. If Alice doesn’t have a valid cookie, the whole attack is useless as the whole point of it is to find that exact cookie value, thus I think it is safe to assume that Alice has one of those.

        As for the cookie blacklist: wouldn’t this list be parsed only after the spoofed data is accepted by OpenSSL on Layer 7 parsing (i.e. too late)? About the only thing I could imaging is that any cookie (or at least the session cookie) would always be cleared when a connection is made over SSLv3, which would make the second such request safe again. But this still feels rather brittle and I’m sure I’m still missing something here.

        Holger.

        1. Purpose of the blacklist would to know if a cookie has been sent over an unsafe connection, so you can expire it and you can also prevent it to reach the backends.
          Then Alice will be prompted a nice page explaining her why she can’t browse her favorite application.

          This is a more polite way than only denying traffic at connection layer. That said, feel free to do what you want!
          The only good way is the one that would meet your requirements.

          Baptiste

          1. Thanks for the feedback. I’m sorry, I didn’t intend to attack you or your proposed solution (which I still think is nifty). I just wanted to find out if this could actually work securely, in which case, we would also use this for sure. Unfortunately, I’m still not convinced 🙂

            While expiring the cookie and not forwarding any requests containing this cookie to the app might actually solve the issue of finding cookies, it doesn’t prevent other vectors, e.g. finding a CSRF token and using this one with an XSS. Trying to expire or hide things on Layer 7 just feels like herding a flock of ducklings to ensure we don’t lose anything.

            And while I love solutions that are backwards-compatible (or at least provide proper error messages), I fear in this case, it just doesn’t work securely 🙁

  2. I think the syntax in the acl in “In SSL forward mode” is incorrect.

    It should be:

    acl sslv3 req_ssl_ver 3

    Im running version 1.4.18 of haproxy and that definitely works for me.

  3. Hello

    Could you please exlain me why you are insisting on ” This must be added in a **frontend** section:” ? I don’t get it because if you apply the reject rule in the backend it should also prevent the request from reaching the backend, right ? What am I missing ?

    1. Yes, you’re right.
      It’s a question of how HAProxy processes the configuration.
      Basically, we always organize it this way: tcp rules, then HTTP rules, deny rules, then other rules.
      In the article we want to prevent unsafe client (those using SSLv3) to use any kind of service or access any application layer information. Hence we close the connection as soon as we can, which is in the frontend.

Leave a Reply

Your email address will not be published. Required fields are marked *