Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit36bb95e

Browse files
committed
libpq: reject extraneous data after SSL or GSS encryption handshake.
libpq collects up to a bufferload of data whenever it reads data fromthe socket. When SSL or GSS encryption is requested during startup,any additional data received with the server's yes-or-no replyremained in the buffer, and would be treated as already-decrypted dataonce the encryption handshake completed. Thus, a man-in-the-middlewith the ability to inject data into the TCP connection could stuffsome cleartext data into the start of a supposedly encryption-protecteddatabase session.This could probably be abused to inject faked responses to theclient's first few queries, although other details of libpq's behaviormake that harder than it sounds. A different line of attack is toexfiltrate the client's password, or other sensitive data that mightbe sent early in the session. That has been shown to be possible witha server vulnerable toCVE-2021-23214.To fix, throw a protocol-violation error if the internal bufferis not empty after the encryption handshake.Our thanks to Jacob Champion for reporting this problem.Security:CVE-2021-23222
1 parentd1bd267 commit36bb95e

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

‎doc/src/sgml/protocol.sgml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,20 @@ SELCT 1/0;<!-- this typo is intentional -->
14711471
and proceed without requesting <acronym>SSL</acronym>.
14721472
</para>
14731473

1474+
<para>
1475+
When <acronym>SSL</acronym> encryption can be performed, the server
1476+
is expected to send only the single <literal>S</literal> byte and then
1477+
wait for the frontend to initiate an <acronym>SSL</acronym> handshake.
1478+
If additional bytes are available to read at this point, it likely
1479+
means that a man-in-the-middle is attempting to perform a
1480+
buffer-stuffing attack
1481+
(<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
1482+
Frontends should be coded either to read exactly one byte from the
1483+
socket before turning the socket over to their SSL library, or to
1484+
treat it as a protocol violation if they find they have read additional
1485+
bytes.
1486+
</para>
1487+
14741488
<para>
14751489
An initial SSLRequest can also be used in a connection that is being
14761490
opened to send a CancelRequest message.
@@ -1532,6 +1546,20 @@ SELCT 1/0;<!-- this typo is intentional -->
15321546
encryption.
15331547
</para>
15341548

1549+
<para>
1550+
When <acronym>GSSAPI</acronym> encryption can be performed, the server
1551+
is expected to send only the single <literal>G</literal> byte and then
1552+
wait for the frontend to initiate a <acronym>GSSAPI</acronym> handshake.
1553+
If additional bytes are available to read at this point, it likely
1554+
means that a man-in-the-middle is attempting to perform a
1555+
buffer-stuffing attack
1556+
(<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
1557+
Frontends should be coded either to read exactly one byte from the
1558+
socket before turning the socket over to their GSSAPI library, or to
1559+
treat it as a protocol violation if they find they have read additional
1560+
bytes.
1561+
</para>
1562+
15351563
<para>
15361564
An initial GSSENCRequest can also be used in a connection that is being
15371565
opened to send a CancelRequest message.

‎src/interfaces/libpq/fe-connect.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,6 +2986,19 @@ PQconnectPoll(PGconn *conn)
29862986
pollres=pqsecure_open_client(conn);
29872987
if (pollres==PGRES_POLLING_OK)
29882988
{
2989+
/*
2990+
* At this point we should have no data already buffered.
2991+
* If we do, it was received before we performed the SSL
2992+
* handshake, so it wasn't encrypted and indeed may have
2993+
* been injected by a man-in-the-middle.
2994+
*/
2995+
if (conn->inCursor!=conn->inEnd)
2996+
{
2997+
appendPQExpBufferStr(&conn->errorMessage,
2998+
libpq_gettext("received unencrypted data after SSL response\n"));
2999+
gotoerror_return;
3000+
}
3001+
29893002
/* SSL handshake done, ready to send startup packet */
29903003
conn->status=CONNECTION_MADE;
29913004
returnPGRES_POLLING_WRITING;
@@ -3085,6 +3098,19 @@ PQconnectPoll(PGconn *conn)
30853098
pollres=pqsecure_open_gss(conn);
30863099
if (pollres==PGRES_POLLING_OK)
30873100
{
3101+
/*
3102+
* At this point we should have no data already buffered.
3103+
* If we do, it was received before we performed the GSS
3104+
* handshake, so it wasn't encrypted and indeed may have
3105+
* been injected by a man-in-the-middle.
3106+
*/
3107+
if (conn->inCursor!=conn->inEnd)
3108+
{
3109+
appendPQExpBufferStr(&conn->errorMessage,
3110+
libpq_gettext("received unencrypted data after GSSAPI encryption response\n"));
3111+
gotoerror_return;
3112+
}
3113+
30883114
/* All set for startup packet */
30893115
conn->status=CONNECTION_MADE;
30903116
returnPGRES_POLLING_WRITING;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp