diff mbox series

[meta-security,scarthgap] libhtp: fix CVE-2024-45797

Message ID 20241018053118.27569-1-hprajapati@mvista.com
State New
Headers show
Series [meta-security,scarthgap] libhtp: fix CVE-2024-45797 | expand

Commit Message

Hitendra Prajapati Oct. 18, 2024, 5:31 a.m. UTC
Upstream-Status: Backport from https://github.com/OISF/libhtp/commit/0d550de551b91d5e57ba23e2b1e2c6430fad6818

Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 .../suricata/files/CVE-2024-45797.patch       | 148 ++++++++++++++++++
 recipes-ids/suricata/libhtp_0.5.45.bb         |   4 +-
 2 files changed, 151 insertions(+), 1 deletion(-)
 create mode 100644 recipes-ids/suricata/files/CVE-2024-45797.patch
diff mbox series

Patch

diff --git a/recipes-ids/suricata/files/CVE-2024-45797.patch b/recipes-ids/suricata/files/CVE-2024-45797.patch
new file mode 100644
index 0000000..3db4625
--- /dev/null
+++ b/recipes-ids/suricata/files/CVE-2024-45797.patch
@@ -0,0 +1,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
+
diff --git a/recipes-ids/suricata/libhtp_0.5.45.bb b/recipes-ids/suricata/libhtp_0.5.45.bb
index cc8285c..604a0ca 100644
--- a/recipes-ids/suricata/libhtp_0.5.45.bb
+++ b/recipes-ids/suricata/libhtp_0.5.45.bb
@@ -4,7 +4,9 @@  require suricata.inc
 
 LIC_FILES_CHKSUM = "file://LICENSE;beginline=1;endline=2;md5=596ab7963a1a0e5198e5a1c4aa621843"
 
-SRC_URI = "git://github.com/OISF/libhtp.git;protocol=https;branch=0.5.x"
+SRC_URI = "git://github.com/OISF/libhtp.git;protocol=https;branch=0.5.x \
+           file://CVE-2024-45797.patch \
+          "
 SRCREV = "8bdfe7b9d04e5e948c8fbaa7472e14d884cc00af"
 
 DEPENDS = "zlib"