]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tls: make version and size checks stricter
authorVictor Julien <vjulien@oisf.net>
Tue, 6 Sep 2022 12:03:46 +0000 (14:03 +0200)
committerVictor Julien <vjulien@oisf.net>
Wed, 21 Sep 2022 04:43:48 +0000 (06:43 +0200)
This way bad records won't buffer lots of stream data.

src/app-layer-ssl.c
src/app-layer-ssl.h

index b034ce46a6cffabd69e8f34e2988998b9b6e7bf8..82069a0a521674572c20864a189ea964220ae4f3 100644 (file)
@@ -197,7 +197,8 @@ SslConfig ssl_config;
 
 #define SSLV3_RECORD_HDR_LEN            5
 #define SSLV3_MESSAGE_HDR_LEN           4
-#define SSLV3_RECORD_MAX_LEN            1 << 14
+/** max length according to RFC 5246 6.2.2 is 2^14 + 1024 */
+#define SSLV3_RECORD_MAX_LEN ((1 << 14) + 1024)
 
 #define SSLV3_CLIENT_HELLO_VERSION_LEN  2
 #define SSLV3_CLIENT_HELLO_RANDOM_LEN  32
@@ -2228,10 +2229,15 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat
         SCLogDebug("record_len %u (input_len %u, parsed %u, ssl_state->curr_connp->record_length %u)",
                 record_len, input_len, parsed, ssl_state->curr_connp->record_length);
 
-        /* records are not supposed to exceed 16384, but the length field is 16 bits. */
+        if (!TLSVersionValid(ssl_state->curr_connp->version)) {
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_RECORD_VERSION);
+            return SSL_DECODER_ERROR(-1);
+        }
+
         if (ssl_state->curr_connp->bytes_processed == SSLV3_RECORD_HDR_LEN &&
                 ssl_state->curr_connp->record_length > SSLV3_RECORD_MAX_LEN) {
             SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_RECORD_LENGTH);
+            return SSL_DECODER_ERROR(-1);
         }
     } else {
         ValidateRecordState(ssl_state->curr_connp);
index 084fa3bc4ba68ca49b7d13dd41958a9d7cdc6325..5febf4185b73a41186927678688edb7cefd23c8c 100644 (file)
@@ -188,6 +188,39 @@ enum {
     TLS_VERSION_13_DRAFT26_FB = 0xfb1a,
 };
 
+static inline bool TLSVersionValid(const uint16_t version)
+{
+    switch (version) {
+        case TLS_VERSION_13:
+        case TLS_VERSION_12:
+        case TLS_VERSION_11:
+        case TLS_VERSION_10:
+        case SSL_VERSION_3:
+
+        case TLS_VERSION_13_DRAFT28:
+        case TLS_VERSION_13_DRAFT27:
+        case TLS_VERSION_13_DRAFT26:
+        case TLS_VERSION_13_DRAFT25:
+        case TLS_VERSION_13_DRAFT24:
+        case TLS_VERSION_13_DRAFT23:
+        case TLS_VERSION_13_DRAFT22:
+        case TLS_VERSION_13_DRAFT21:
+        case TLS_VERSION_13_DRAFT20:
+        case TLS_VERSION_13_DRAFT19:
+        case TLS_VERSION_13_DRAFT18:
+        case TLS_VERSION_13_DRAFT17:
+        case TLS_VERSION_13_DRAFT16:
+        case TLS_VERSION_13_PRE_DRAFT16:
+        case TLS_VERSION_13_DRAFT20_FB:
+        case TLS_VERSION_13_DRAFT21_FB:
+        case TLS_VERSION_13_DRAFT22_FB:
+        case TLS_VERSION_13_DRAFT23_FB:
+        case TLS_VERSION_13_DRAFT26_FB:
+            return true;
+    }
+    return false;
+}
+
 typedef struct SSLCertsChain_ {
     uint8_t *cert_data;
     uint32_t cert_len;