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
).