2

On MongoDB I have enabled SSL/TLS feature to encrypt data transmission between client and server. But what I have done is to generate a self-signed certificate using openssl in linux.

The question is how someone can perform man in the middle attack while I own the private key and no one else has it? Why MiTM cannot be performed when it is purchased from a CA?


My MongoDB connection implementation is easy as below:

pymongo.MongoClient('172.15.141.190:27017', ssl=True, ssl_crlfile='ANY_KEY.pem')

And mongoDB config is:

net:   
    port: 27017   
    bindIp: 0.0.0.0   
    ssl:
        mode: preferSSL
        PEMKeyFile: /etc/ssl/mongodb.pem
Alireza
  • 1,280
  • 1
  • 20
  • 26

2 Answers2

5

TL;DR: Using self-signed certificates does not mean MITM is possible and using a certificate issued by a public CA does not mean MITM is impossible. But, it is more likely that MITM is possible if self-signed certificates are used because the clients dealing with self-signed certificates often deal with these in the wrong way.


Using a self-signed certificate does not allow MITM in general and using a certificate issued by a public CA does not protect against MITM in general. Apart from keeping the private key private the important protection against MITM attacks is not what kind of certificate is used on the server but how this certificate is checked on the client, i.e. if the server gets properly authenticated using a certificate or not.

The established way to authenticate a server using a certificate signed by a public CA is to check the subject of the certificate, trust chain, expiration etc - see SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate? for details. But if a client is not doing this checks or not doing these checks properly an attacker in the path might instead provide its own certificate and the client will not notice. In the past such kind of errors happened due to ignorance or due to bugs, for example not checking certificates at all, not validating the subject, not checking basic constraints etc.

With self-signed certificates proper authentication of the server is doable too: if the client knows the certificate to expect (or its public key, or a hash of it...) up front the client can check that the delivered certificate matches the expected one. This kind of verification is actually properly done in many use cases. But in many other cases it is done wrong: it is not uncommon that clients simply have all certificate checks disabled completely if they expect a self-signed certificate instead of expecting a specific self-signed certificate. With such broken clients MITM is easy since the attacker could just use an arbitrary certificate and the client will accept it.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • I generated a new pem cert named `mitm.pem` using openssl and provided it to `MongoDB pyMongo` client, it didn't blame at all about the key! So does that mean that `pyMongo` client is not doing the check? Is it useless using TLS in this scenario? – Alireza May 01 '18 at 07:26
  • Ah, Steffen! You again;) – Tobi Nary May 01 '18 at 07:32
  • @ALH: given [the documentation](http://api.mongodb.com/python/current/examples/tls.html) it should verify certificates by default. But, I'm not sure how your setup really looks like, i.e. what certificate you have configured at MongoDB, how you have specified the certificate to expect in Python, and how do you exactly checked that it accepts arbitrary certificates. – Steffen Ullrich May 01 '18 at 07:47
  • Could you look at the question again, I have added the code. Tnx. – Alireza May 01 '18 at 07:54
  • @ALH: you are using `ssl_crlfile` - this is for CRL and not for certificates. `ssl_ca_certs` is the key you should use to specify a file for CA's - but this only works if your self-signed certificate is a CA too (not all are created this way). – Steffen Ullrich May 01 '18 at 07:57
  • OK, I removed it. I provided `ssl_certfile='mongodb.pem` but it gives error `SSL handshake failed: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed`. – Alireza May 01 '18 at 08:00
  • @ALH: `ssl_certfile` is not the correct option either. It is used to provide a client certificate and not the server certificate to check. Please take the time to read the documentation more thoroughly. – Steffen Ullrich May 01 '18 at 08:03
2

A man in the middle attack is possible without knowledge of your private key by terminating the connection with your server and having a second connection with the client.

Wether this is actually possible has nothing to do with your private key but rather how the trust of the corresponding public key is managed within the client.

While obtaining a certificate from a CA might improve security over “trust any self signed certificate” because well trusted Trust Ankers are used, restricting trust on your actual self signed certificate offers even better security.

However, there is the off chance that you used a prime number on key generation that someone else used as well. In that case, your key is easily obtained by performing simple arithmetics.

Tobi Nary
  • 14,302
  • 8
  • 43
  • 58