Skip to content

Commit 3323e90

Browse files
committed
[MDEV-31585] Stop trusting or relying on client identifying information sent prior to the TLS handshake
The server has heretofore improperly mishandled—and TRUSTED—information sent in the plaintext login request packet sent prior to the TLS handshake. As a result of this, the client is *forced* to send excessive and exploitable identifying information in the pre-TLS-handshake plaintext login packet. That client-side vulnerability is CONC-654. This modifies the server to stop relying on any of the information in the pre-TLS-handshake plaintext login packet EXCEPT for the single bit that tells it that a TLS handshake will follow. It furthermore adds an "extended capability" bit to the server greeting packet, which informs the client that it is safe to send a bare-bones dummy packet containing ONLY the instruction that a TLS handshake will follow: /* Server does not grievously mishandle information sent in the plaintext * login request packet sent prior to the TLS handshake. As a result, the * client can safely send an empty/dummy packet contianing no * identifying information. Indicates that MDEV-31585 has been fixed. * Since ??.?. */ #define MARIADB_CLIENT_CAN_SEND_DUMMY_HANDSHAKE_PACKET (1ULL << 37)
1 parent fc45d4e commit 3323e90

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

include/mysql_com.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ enum enum_indicator_type
296296
/* support of array binding */
297297
#define MARIADB_CLIENT_STMT_BULK_OPERATIONS (1ULL << 34)
298298

299+
/* Server doesn't improperly read the pre-TLS dummy packet beyond the initial 2 bytes */
300+
#define CLIENT_CAN_SEND_DUMMY_HANDSHAKE_PACKET (1ULL << 37)
301+
299302
#ifdef HAVE_COMPRESS
300303
#define CAN_CLIENT_COMPRESS CLIENT_COMPRESS
301304
#else

libmariadb

sql/sql_acl.cc

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12757,6 +12757,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
1275712757
thd->client_capabilities|= CLIENT_TRANSACTIONS;
1275812758

1275912759
thd->client_capabilities|= CAN_CLIENT_COMPRESS;
12760+
thd->client_capabilities|= CLIENT_CAN_SEND_DUMMY_HANDSHAKE_PACKET;
1276012761

1276112762
if (ssl_acceptor_fd)
1276212763
{
@@ -13253,30 +13254,19 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
1325313254
*/
1325413255
DBUG_ASSERT(net->read_pos[pkt_len] == 0);
1325513256

13256-
ulonglong client_capabilities= uint2korr(net->read_pos);
13257-
compile_time_assert(sizeof(client_capabilities) >= 8);
13258-
if (client_capabilities & CLIENT_PROTOCOL_41)
13257+
ushort first_two_bytes_of_client_capabilities= uint2korr(net->read_pos);
13258+
if (first_two_bytes_of_client_capabilities & CLIENT_SSL)
1325913259
{
13260-
if (pkt_len < 32)
13261-
DBUG_RETURN(packet_error);
13262-
client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
13263-
if (!(client_capabilities & CLIENT_MYSQL))
13264-
{
13265-
// it is client with mariadb extensions
13266-
ulonglong ext_client_capabilities=
13267-
(((ulonglong)uint4korr(net->read_pos + 28)) << 32);
13268-
client_capabilities|= ext_client_capabilities;
13269-
}
13270-
}
13271-
13272-
/* Disable those bits which are not supported by the client. */
13273-
compile_time_assert(sizeof(thd->client_capabilities) >= 8);
13274-
thd->client_capabilities&= client_capabilities;
13260+
/* Client wants to use TLS. This packet is really just a
13261+
* dummy which gets sent before the TLS handshake, in order
13262+
* to trigger the server (us) to start the TLS handshake.
13263+
*
13264+
* We should ignore everything else in this packet until
13265+
* after the TLS handshake.
13266+
*/
1327513267

13276-
DBUG_PRINT("info", ("client capabilities: %llu", thd->client_capabilities));
13277-
if (thd->client_capabilities & CLIENT_SSL)
13278-
{
1327913268
unsigned long errptr __attribute__((unused));
13269+
DBUG_PRINT("info", ("client capabilities have TLS/SSL bit set"));
1328013270

1328113271
/* Do the SSL layering. */
1328213272
if (!ssl_acceptor_fd)
@@ -13297,6 +13287,10 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
1329713287
DBUG_PRINT("info", ("Immediately following IO layer change: vio_type=%s",
1329813288
safe_vio_type_name(thd->net.vio)));
1329913289

13290+
/* Now we are using TLS. The client will resend its REAL
13291+
* handshake packet, containing complete credentials and
13292+
* capability information.
13293+
*/
1330013294
DBUG_PRINT("info", ("Reading user information over SSL layer"));
1330113295
pkt_len= my_net_read(net);
1330213296
if (unlikely(pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE))
@@ -13305,8 +13299,33 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
1330513299
pkt_len));
1330613300
DBUG_RETURN(packet_error);
1330713301
}
13302+
13303+
/* Re-load the FIRST TWO BYTES of the client handshake packet */
13304+
first_two_bytes_of_client_capabilities = uint2korr(net->read_pos);
1330813305
}
1330913306

13307+
ulonglong client_capabilities= (ulonglong) first_two_bytes_of_client_capabilities;
13308+
compile_time_assert(sizeof(client_capabilities) >= 8);
13309+
13310+
DBUG_PRINT("info", ("client capabilities: %llu", thd->client_capabilities));
13311+
if (client_capabilities & CLIENT_PROTOCOL_41)
13312+
{
13313+
if (pkt_len < 32)
13314+
DBUG_RETURN(packet_error);
13315+
client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
13316+
if (!(client_capabilities & CLIENT_MYSQL))
13317+
{
13318+
// it is client with mariadb extensions
13319+
ulonglong ext_client_capabilities=
13320+
(((ulonglong)uint4korr(net->read_pos + 28)) << 32);
13321+
client_capabilities|= ext_client_capabilities;
13322+
}
13323+
}
13324+
13325+
/* Disable those bits which are not supported by the client. */
13326+
compile_time_assert(sizeof(thd->client_capabilities) >= 8);
13327+
thd->client_capabilities&= client_capabilities;
13328+
1331013329
if (client_capabilities & CLIENT_PROTOCOL_41)
1331113330
{
1331213331
thd->max_client_packet_length= uint4korr(net->read_pos+4);

0 commit comments

Comments
 (0)