diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-11-08 11:01:43 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-11-08 11:01:43 -0500 |
commit | e92ed93e8eb76ee0701b42d4f0ce94e6af3fc741 (patch) | |
tree | 747c7536594cfb590e0b56a6cdf92c6d2c7defe9 /src/backend/postmaster/postmaster.c | |
parent | 7c0a78f089980cec45927aa3160add1781aed402 (diff) |
Reject extraneous data after SSL or GSS encryption handshake.
The server collects up to a bufferload of data whenever it reads data
from the client socket. When SSL or GSS encryption is requested
during startup, any additional data received with the initial
request message remained in the buffer, and would be treated as
already-decrypted data once the encryption handshake completed.
Thus, a man-in-the-middle with the ability to inject data into the
TCP connection could stuff some cleartext data into the start of
a supposedly encryption-protected database session.
This could be abused to send faked SQL commands to the server,
although that would only work if the server did not demand any
authentication data. (However, a server relying on SSL certificate
authentication might well not do so.)
To fix, throw a protocol-violation error if the internal buffer
is not empty after the encryption handshake.
Our thanks to Jacob Champion for reporting this problem.
Security: CVE-2021-23214
Diffstat (limited to 'src/backend/postmaster/postmaster.c')
-rw-r--r-- | src/backend/postmaster/postmaster.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 5775fc0c091..1e0936e5b48 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -2050,6 +2050,18 @@ retry1: #endif /* + * At this point we should have no data already buffered. If we do, + * it was received before we performed the SSL handshake, so it wasn't + * encrypted and indeed may have been injected by a man-in-the-middle. + * We report this case to the client. + */ + if (pq_buffer_has_data()) + ereport(FATAL, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("received unencrypted data after SSL request"), + errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack."))); + + /* * regular startup packet, cancel, etc packet should follow, but not * another SSL negotiation request, and a GSS request should only * follow if SSL was rejected (client may negotiate in either order) @@ -2082,6 +2094,18 @@ retry1: #endif /* + * At this point we should have no data already buffered. If we do, + * it was received before we performed the GSS handshake, so it wasn't + * encrypted and indeed may have been injected by a man-in-the-middle. + * We report this case to the client. + */ + if (pq_buffer_has_data()) + ereport(FATAL, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("received unencrypted data after GSSAPI encryption request"), + errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack."))); + + /* * regular startup packet, cancel, etc packet should follow, but not * another GSS negotiation request, and an SSL request should only * follow if GSS was rejected (client may negotiate in either order) |