CVE-2024-23837: Insufficient Information (NVD-CWE-noinfo)
value: LibHTP is a security-aware parser for the HTTP protocol. Crafted traffic can cause excessive processing time of HTTP headers, leading to denial of service. This issue is addressed in 0.5.46.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-02-26T16:27Z
Repository: https://github.com/OISF/libhtp
Language: C
Files changed: htp/htp_private.h, htp/htp_request.c, htp/htp_response.c
Commit date: 2024-01-23 13:58:21 +0100
Commit message: headers: limit the size of folded headers

Ticket: #6444

So as to limit the quadratic complexity of always reallocating
to push more bytes in header value

Diff: diff --git a/htp/htp_private.h b/htp/htp_private.h
index 5a4e68f..9bcf19d 100644
--- a/htp/htp_private.h
+++ b/htp/htp_private.h
@@ -260,7 +260,10 @@ size_t strlcpy(char *dst, const char *src, size_t size);
 
 #ifdef	__cplusplus
 }
 #endif
 
+// as CURL_MAX_HTTP_HEADER
+#define HTP_MAX_HEADER_FOLDED 102400
+
 #endif	/* _HTP_PRIVATE_H */
 
diff --git a/htp/htp_request.c b/htp/htp_request.c
index 57e5d0e..2138831 100644
--- a/htp/htp_request.c
+++ b/htp/htp_request.c
@@ -712,14 +712,18 @@ htp_status_t htp_connp_REQ_HEADERS(htp_connp_t *connp) {
                         trim++;
                     }
                     connp->in_header = bstr_dup_mem(data + trim, len - trim);
                     if (connp->in_header == NULL) return HTP_ERROR;
                 } else {
-                    // Add to the existing header.                    
-                    bstr *new_in_header = bstr_add_mem(connp->in_header, data, len);
-                    if (new_in_header == NULL) return HTP_ERROR;
-                    connp->in_header = new_in_header;
+                    // Add to the existing header.
+                    if (bstr_len(connp->in_header) < HTP_MAX_HEADER_FOLDED) {
+                        bstr *new_in_header = bstr_add_mem(connp->in_header, data, len);
+                        if (new_in_header == NULL) return HTP_ERROR;
+                        connp->in_header = new_in_header;
+                    } else {
+                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request field length exceeds folded maximum");
+                    }
                 }
             }
 
             htp_connp_req_clear_buffer(connp);
         }
diff --git a/htp/htp_response.c b/htp/htp_response.c
index 81cbf98..121004c 100644
--- a/htp/htp_response.c
+++ b/htp/htp_response.c
@@ -976,14 +976,18 @@ htp_status_t htp_connp_RES_HEADERS(htp_connp_t *connp) {
                         connp->out_header = bstr_dup_mem(data+1, len-1);
                         if (connp->out_header == NULL)
                             return HTP_ERROR;
                     } else {
                         // Add to the existing header.
-                        bstr *new_out_header = bstr_add_mem(connp->out_header, data, len);
-                        if (new_out_header == NULL)
-                            return HTP_ERROR;
-                        connp->out_header = new_out_header;
+                        if (bstr_len(connp->out_header) < HTP_MAX_HEADER_FOLDED) {
+                            bstr *new_out_header = bstr_add_mem(connp->out_header, data, len);
+                            if (new_out_header == NULL)
+                                return HTP_ERROR;
+                            connp->out_header = new_out_header;
+                        } else {
+                            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Response field length exceeds folded maximum");
+                        }
                     }
                 }
             }
 
             htp_connp_res_clear_buffer(connp);

Vulnerable code:                     // Add to the existing header.                    
                    bstr *new_in_header = bstr_add_mem(connp->in_header, data, len);
                    if (new_in_header == NULL) return HTP_ERROR;
                    connp->in_header = new_in_header;
                        bstr *new_out_header = bstr_add_mem(connp->out_header, data, len);
                        if (new_out_header == NULL)
                            return HTP_ERROR;
                        connp->out_header = new_out_header;
Fixed code: // as CURL_MAX_HTTP_HEADER
#define HTP_MAX_HEADER_FOLDED 102400

                    // Add to the existing header.
                    if (bstr_len(connp->in_header) < HTP_MAX_HEADER_FOLDED) {
                        bstr *new_in_header = bstr_add_mem(connp->in_header, data, len);
                        if (new_in_header == NULL) return HTP_ERROR;
                        connp->in_header = new_in_header;
                    } else {
                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request field length exceeds folded maximum");
                    }
                        if (bstr_len(connp->out_header) < HTP_MAX_HEADER_FOLDED) {
                            bstr *new_out_header = bstr_add_mem(connp->out_header, data, len);
                            if (new_out_header == NULL)
                                return HTP_ERROR;
                            connp->out_header = new_out_header;
                        } else {
                            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Response field length exceeds folded maximum");
                        }