Disallow SSL renegotiation
authorMichael Paquier
Tue, 25 May 2021 01:11:13 +0000 (10:11 +0900)
committerMichael Paquier
Tue, 25 May 2021 01:11:13 +0000 (10:11 +0900)
SSL renegotiation is already disabled as of 48d23c72, however this does
not prevent the server to comply with a client willing to use
renegotiation.  In the last couple of years, renegotiation had its set
of security issues and flaws (like the recent CVE-2021-3449), and it
could be possible to crash the backend with a client attempting
renegotiation.

This commit takes one extra step by disabling renegotiation in the
backend in the same way as SSL compression (f9264d15) or tickets
(97d3a0b0).  OpenSSL 1.1.0h has added an option named
SSL_OP_NO_RENEGOTIATION able to achieve that.  In older versions
there is an option called SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS that
was undocumented, and could be set within the SSL object created when
the TLS connection opens, but I have decided not to use it, as it feels
trickier to rely on, and it is not official.  Note that this option is
not usable in OpenSSL < 1.1.0h as the internal contents of the *SSL
object are hidden to applications.

SSL renegotiation concerns protocols up to TLSv1.2.

Per original report from Robert Haas, with a patch based on a suggestion
by Andres Freund.

Author: Michael Paquier
Reviewed-by: Daniel Gustafsson
Discussion: https://postgr.es/m/[email protected]
Backpatch-through: 9.6

src/backend/libpq/be-secure-openssl.c

index f88779c6d281f5f8691a28fc89f227057efb0c10..d1705acdc29528b9d47d53a1703ce80e62b69324 100644 (file)
@@ -248,6 +248,16 @@ be_tls_init(bool isServerStart)
    /* disallow SSL session caching, too */
    SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
 
+#ifdef SSL_OP_NO_RENEGOTIATION
+
+   /*
+    * Disallow SSL renegotiation, option available since 1.1.0h.  This
+    * concerns only TLSv1.2 and older protocol versions, as TLSv1.3 has no
+    * support for renegotiation.
+    */
+   SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION);
+#endif
+
    /* set up ephemeral DH and ECDH keys */
    if (!initialize_dh(context, isServerStart))
        goto error;