1

If one is using MongoDB enterprise, or built MongoDB from source using the -ssl option (as described here), is that MongoDB vulnerable to the heartbleed bug?

I know mongo needed openssl-devel to be installed on the machine for the build to work. But is it now using that vulnerable openssl version internally and now mongoDB needs to be entirely rebuilt or updated? Or if you update openssl on the server that is sufficient?

delemach
  • 13
  • 1
  • 3
  • 1
    If the build was static, rebuild needed. If shared library was used, disconnect from Web, update from your build rig, reboot, reissue certs, restart. – Deer Hunter Apr 09 '14 at 08:13
  • Thanks, but how do I know if the build was static or not? I built mongo using the -ssl flag, eg `scons -j 8 --ssl --64 all` – delemach Apr 09 '14 at 08:37

1 Answers1

5

The answer to this (not just MongoDB, but any program) is quite system dependent.

If you are running MongoDB with SSL enabled at compile time, and enabled at run-time, and it's using a vulnerable OpenSSL (1.0.1—1.0.1f with hearbeat not explicitly removed), then yes.

If you are only listening on localhost, or you have packet filtering/firewalling to allow only trusted clients you are less at risk, but you are still vulnerable of course.

OpenSSL provides two libraries, libssl and libcrypto, MongoDB uses both (this flaw is contained only in libssl). If OpenSSL is dynamically linked in, you should be able to just update OpenSSL and restart the affected processes. If it is statically linked in, you need to update OpenSSL, rebuild the affected software, stop all affected daemons/processes, reinstall, then restart them. Whether you upgrade to 1.0.1g, or a patched 1.0.1(≤f) with the problem feature disabled, see below for steps to confirm that you've properly updated. Then get busy picking up the pieces if you have untrusted users/connections.

On most *nix systems you can run ldd against the binaries, this will confirm if OpenSSL (i.e. libssl.so) is dynamically linked. This only proves a binary uses OpenSSL, no dynamic dependency does not always mean it does not use OpenSSL: it may be static, loaded by a different dependent library, or even loaded on-demand (e.g. Apache httpd loading mod_ssl.so). mongod links directly against OpenSSL though..

An alternate approach to ldd which may be more reliable:

  • determine the process PID(s) then as root, run lsof -p PID or lsof -p PID1,PID2,... to see if it has the library open
  • on Linux you can instead cat /proc/PID/maps and check which libraries are mapped in

The above only work when a dynamic library (libssl.so) is used, if the static library (libssl.a) was used the code is present directly in the binaries, not loaded from an external library (which makes it harder to upgrade of course, most systems use dynamic OpenSSL libraries partly for this reason).

Some software (I wish they all did), tells you what build and run-time features/libs they use, by way of logging at startup or with verbose/debug/version/help command line options. For MongoDB use mongodb --version for this. In 2.6, this calls the API function SSLeay_version(), so it will correctly show the run-time (not the build-time) version of OpenSSL, but it doesn't tell you if it's statically or dynamically linked. In the case of Mongodb, you know OpenSSL is enabled, and since the mongodb excutable is directly linked against the SSL libraries, ldd will tell you if they're dynamically linked or not.

In other cases, you might be stuck with something unpretty to try and determine what library version might be statically linked: strings -a or objdump -s.


MongoDB provides an SSL/TLS TCP service when SSL is enabled, check if it's listening on anything other than localhost via netstat, or by attempting a connection (probably port 27017). The lsof output also shows listening ports, or try lsof -p $PID -a -i tcp for just TCP (note MongoDB doesn't run TLS on a distinct port).

If you have a recent(-ish) nmap you can use its mongodb-info script:

$ nmap -vvv -sV --version-all --script mongodb-info.nse -p 27017 localhost
[...]
PORT      STATE SERVICE VERSION
27017/tcp open  mongodb MongoDB 2.6.0
| mongodb-info: 
[...]
|     compilerFlags = -Wnon-virtual-dtor -Woverloaded-virtual -fPIC -fno-strict-\
        aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-\
        pch -pipe -O3 -Wno-unused-function -Wno-deprecated-declarations -fno-builtin-\
        memcmp
|     loaderFlags = -fPIC -pthread -Wl,-z,now -rdynamic
|     debug = false
|     version = 2.6.0
|     OpenSSLVersion = OpenSSL 1.0.1e 11 Feb 2013
[...]

You can also probe for the problematic TLS extension with OpenSSL's s_client, though take care to use a recent version which sends a TLS client hello and has the heartbeat extension enabled, an SSL2 client hello will not enable the extension, nor will a client without heartbeat support:

echo Q | openssl s_client -connect myhost:27017 -tls1 -tlsextdebug

This works regardless of the SSL connection preference you are using for MongoDB.

The server extensions will be listed within the first few lines of output, before certificate details:

CONNECTED(00000003)
TLS server extension "renegotiation info" (id=65281), len=1
0001 - <SPACES/NULS>
TLS server extension "session ticket" (id=35), len=0
TLS server extension "heartbeat" (id=15), len=1
[...]

This alone doesn't prove you are vulnerable, or that you are running OpenSSL, or even a specific OpenSSL version. If you like living dangerously, you may wish to attempt to use one of the POC scripts. (I've used ssltest.py successfully, and without crashing Apache httpd or mongod processes, YMMV.)

To check your OpenSSL version and options use openssl version -a, the presence of -DOPENSSL_NO_HEARTBEATS indicates the problematic feature has been disabled at build time. There's no guarantee that the openssl command will use the same library as anything else, to really check thoroughly you should identify all likely libraries:

find / -name "libssl.*"

The default behaviour (gcc+binutils) when searching for libraries is "first found" honoring the library directory ordering, when both dynamic and static versions of libraries found together it prefers dynamic libraries (unless -static is used, this isn't an option with MongoDB since it's implemented in C++). Even if libssl.so is present OpenSSL could still be statically linked, though for a normal build with libssl.so available, it will dynamic not be static (the MongoDB SCons build makes no special attempt to use libssl.a).

mr.spuratic
  • 7,977
  • 26
  • 37
  • Thanks for the very detailed answer! Using `ldd` I see: `libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007f4febfd7000)` and using `cat proc/PID/maps` I see: `7fec227c8000-7fec22829000 r-xp 00000000 fc:00 262873 /usr/lib64/libssl.so.1.0.1e` I've [patched](http://lists.centos.org/pipermail/centos-announce/2014-April/020249.html) and restarted everything so I think I'm good. Thanks again! – delemach Apr 11 '14 at 05:40