summaryrefslogtreecommitdiffstats
path: root/recipes-ids/suricata/files/CVE-2024-45797.patch
blob: 3db4625224dd306a9832eb509d0be7dd54f3edcc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
From 0d550de551b91d5e57ba23e2b1e2c6430fad6818 Mon Sep 17 00:00:00 2001
From: Philippe Antoine <contact@catenacyber.fr>
Date: Mon, 12 Aug 2024 14:06:40 +0200
Subject: [PATCH] headers: put a configurable limit on their numbers

So as to avoid quadratic complexity

Ticket: 7191

Upstream-Status: Backport [https://github.com/OISF/libhtp/commit/0d550de551b91d5e57ba23e2b1e2c6430fad6818]
CVE: CVE-2024-45797
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 htp/htp_config.c           |  8 ++++++++
 htp/htp_config.h           |  8 ++++++++
 htp/htp_config_private.h   |  6 ++++++
 htp/htp_core.h             |  1 +
 htp/htp_request_generic.c  | 11 +++++++++++
 htp/htp_response_generic.c | 10 ++++++++++
 6 files changed, 44 insertions(+)

diff --git a/htp/htp_config.c b/htp/htp_config.c
index 767458f..9e0eee3 100644
--- a/htp/htp_config.c
+++ b/htp/htp_config.c
@@ -145,6 +145,8 @@ static unsigned char bestfit_1252[] = {
     0xff, 0x5d, 0x7d, 0xff, 0x5e, 0x7e, 0x00, 0x00, 0x00
 };
 
+#define HTP_HEADERS_LIMIT 1024
+
 htp_cfg_t *htp_config_create(void) {
     htp_cfg_t *cfg = calloc(1, sizeof (htp_cfg_t));
     if (cfg == NULL) return NULL;
@@ -163,6 +165,7 @@ htp_cfg_t *htp_config_create(void) {
     cfg->response_lzma_layer_limit = 1; // default is only one layer
     cfg->compression_bomb_limit = HTP_COMPRESSION_BOMB_LIMIT;
     cfg->compression_time_limit = HTP_COMPRESSION_TIME_LIMIT_USEC;
+    cfg->number_headers_limit = HTP_HEADERS_LIMIT;
     cfg->allow_space_uri = 0;
 
     // Default settings for URL-encoded data.
@@ -542,6 +545,11 @@ void htp_config_set_compression_time_limit(htp_cfg_t *cfg, size_t useclimit) {
     }
 }
 
+void htp_config_set_number_headers_limit(htp_cfg_t *cfg, uint32_t limit) {
+    if (cfg == NULL) return;
+    cfg->number_headers_limit = limit;
+}
+
 void htp_config_set_log_level(htp_cfg_t *cfg, enum htp_log_level_t log_level) {
     if (cfg == NULL) return;
     cfg->log_level = log_level;
diff --git a/htp/htp_config.h b/htp/htp_config.h
index d1365dc..ed0eaeb 100644
--- a/htp/htp_config.h
+++ b/htp/htp_config.h
@@ -466,6 +466,14 @@ void htp_config_set_compression_time_limit(htp_cfg_t *cfg, size_t useclimit);
  */
 void htp_config_set_log_level(htp_cfg_t *cfg, enum htp_log_level_t log_level);
 
+/**
+ * Configures the maximum number of headers LibHTP will accept per request or response.
+ *
+ * @param[in] cfg
+ * @param[in] limit
+ */
+void htp_config_set_number_headers_limit(htp_cfg_t *cfg, uint32_t limit);
+
 /**
  * Configures how the server reacts to encoded NUL bytes. Some servers will stop at
  * at NUL, while some will respond with 400 or 404. When the termination option is not
diff --git a/htp/htp_config_private.h b/htp/htp_config_private.h
index 5f1d60d..ecc8717 100644
--- a/htp/htp_config_private.h
+++ b/htp/htp_config_private.h
@@ -360,6 +360,12 @@ struct htp_cfg_t {
 
     /** Whether to decompress compressed request bodies. */
     int request_decompression_enabled;
+
+    /** Maximum number of transactions. */
+    uint32_t max_tx;
+
+    /** Maximum number of headers. */
+    uint32_t number_headers_limit;
 };
 
 #ifdef	__cplusplus
diff --git a/htp/htp_core.h b/htp/htp_core.h
index e4c933e..7c23212 100644
--- a/htp/htp_core.h
+++ b/htp/htp_core.h
@@ -235,6 +235,7 @@ enum htp_file_source_t {
 #define HTP_REQUEST_INVALID                0x100000000ULL
 #define HTP_REQUEST_INVALID_C_L            0x200000000ULL
 #define HTP_AUTH_INVALID                   0x400000000ULL
+#define HTP_HEADERS_TOO_MANY               0x800000000ULL
 
 #define HTP_MAX_HEADERS_REPETITIONS 64
 
diff --git a/htp/htp_request_generic.c b/htp/htp_request_generic.c
index 435cf0a..1350e57 100644
--- a/htp/htp_request_generic.c
+++ b/htp/htp_request_generic.c
@@ -120,6 +120,17 @@ htp_status_t htp_process_request_header_generic(htp_connp_t *connp, unsigned cha
         bstr_free(h->value);
         free(h);
     } else {
+        if (htp_table_size(connp->in_tx->request_headers) > connp->cfg->number_headers_limit) {
+            if (!(connp->in_tx->flags & HTP_HEADERS_TOO_MANY)) {
+                connp->in_tx->flags |= HTP_HEADERS_TOO_MANY;
+                htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Too many request headers");
+            }
+            bstr_free(h->name);
+            bstr_free(h->value);
+            free(h);
+            // give up on what comes next
+            return HTP_ERROR;
+        }
         // Add as a new header.
         if (htp_table_add(connp->in_tx->request_headers, h->name, h) != HTP_OK) {
             bstr_free(h->name);
diff --git a/htp/htp_response_generic.c b/htp/htp_response_generic.c
index f5fa59e..69da625 100644
--- a/htp/htp_response_generic.c
+++ b/htp/htp_response_generic.c
@@ -321,6 +321,16 @@ htp_status_t htp_process_response_header_generic(htp_connp_t *connp, unsigned ch
         bstr_free(h->value);
         free(h);       
     } else {
+        if (htp_table_size(connp->out_tx->response_headers) > connp->cfg->number_headers_limit) {
+            if (!(connp->out_tx->flags & HTP_HEADERS_TOO_MANY)) {
+                connp->out_tx->flags |= HTP_HEADERS_TOO_MANY;
+                htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Too many response headers");
+            }
+            bstr_free(h->name);
+            bstr_free(h->value);
+            free(h);
+            return HTP_ERROR;
+        }
         // Add as a new header.
         if (htp_table_add(connp->out_tx->response_headers, h->name, h) != HTP_OK) {
             bstr_free(h->name);
-- 
2.25.1