CVE-2024-28871 (published 2024-04-04T15:15Z)

LibHTP is a security-aware parser for the HTTP protocol and the related bits and pieces. Version 0.5.46 may parse malformed request traffic, leading to excessive CPU usage. Version 0.5.47 contains a patch for the issue. No known workarounds are available.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/OISF/libhtp
commit_details: repo_url: https://github.com/OISF/libhtp
author: Philippe Antoine
author_date: 2024-02-08 16:08:05+01:00
msg: request: limit probing after missing protocol

And do not consider HTTP/0.9 if there is too much junk afterward.

Avoids quadratic complexity with probing many whitespaces lines.

Ticket: 6757

Fixes: bf618ec7f243 ("http0.9: process headers if there are non-space characters")
repository: repo_url: https://github.com/OISF/libhtp
repo_name: OISF/libhtp
description: LibHTP is a security-aware parser for the HTTP protocol and the related bits and pieces. 
repo_language: C++
owner: OISF
file_changes: filename: htp_request.c
change_type: ModificationType.MODIFY
diff: @@ -732,6 +732,14 @@ htp_status_t htp_connp_REQ_HEADERS(htp_connp_t *connp) {
     return HTP_ERROR;
 }
 
+// HTTP/0.9 is supposed to be only a request line without protocol.
+// Libhtp will still consider the request to be HTTP/0.9 if there
+// are some junk whitespaces after that request line.
+// Libhtp allows the small value of 16 extra bytes/whitespaces,
+// otherwise we consider it to be a HTTP/1.x request with missing protocol.
+// It is unlikely to meet HTTP/0.9, and we want to limit probing.
+#define HTTP09_MAX_JUNK_LEN 16
+
 /**
  * Determines request protocol.
  *
@@ -749,6 +757,14 @@ htp_status_t htp_connp_REQ_PROTOCOL(htp_connp_t *connp) {
         // Let's check if the protocol was simply missing
         int64_t pos = connp->in_current_read_offset;
         // Probe if data looks like a header line
+        if (connp->in_current_len > connp->in_current_read_offset + HTTP09_MAX_JUNK_LEN) {
+            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request line: missing protocol");
+            connp->in_tx->is_protocol_0_9 = 0;
+            // Switch to request header parsing.
+            connp->in_state = htp_connp_REQ_HEADERS;
+            connp->in_tx->request_progress = HTP_REQUEST_HEADERS;
+            return HTP_OK;
+        }
         while (pos < connp->in_current_len) {
             if (!htp_is_space(connp->in_current_data[pos])) {
                 htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request line: missing protocol");

programming_language: C
repo_url: https://github.com/OISF/libhtp
commit_details: repo_url: https://github.com/OISF/libhtp
author: Philippe Antoine
author_date: 2023-04-07 10:54:52+02:00
msg: http0.9: process headers if there are non-space characters

Previously, we fell back on HTTP/0.9 if there was a missing protocol
except if the following line cintained a colon.

This makes libhtp stricter to consider a transaction as 0.9
by only accepting if we have spaces after the request line

as done in libhtp-rs

Ticket: 6643
repository: repo_url: https://github.com/OISF/libhtp
repo_name: OISF/libhtp
description: LibHTP is a security-aware parser for the HTTP protocol and the related bits and pieces. 
repo_language: C++
owner: OISF
file_changes: filename: htp_request.c
change_type: ModificationType.MODIFY
diff: @@ -744,21 +744,15 @@ htp_status_t htp_connp_REQ_PROTOCOL(htp_connp_t *connp) {
     } else {
         // Let's check if the protocol was simply missing
         int64_t pos = connp->in_current_read_offset;
-        int afterspaces = 0;
         // Probe if data looks like a header line
         while (pos < connp->in_current_len) {
-            if (connp->in_current_data[pos] == ':') {
+            if (!htp_is_space(connp->in_current_data[pos])) {
                 htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request line: missing protocol");
                 connp->in_tx->is_protocol_0_9 = 0;
                 // Switch to request header parsing.
                 connp->in_state = htp_connp_REQ_HEADERS;
                 connp->in_tx->request_progress = HTP_REQUEST_HEADERS;
                 return HTP_OK;
-            } else if (htp_is_lws(connp->in_current_data[pos])) {
-                // Allows spaces after header name
-                afterspaces = 1;
-            } else if (htp_is_space(connp->in_current_data[pos]) || afterspaces == 1) {
-                break;
             }
             pos++;
         }

programming_language: C
filename: test_main.cpp
change_type: ModificationType.MODIFY
diff: @@ -558,7 +558,6 @@ TEST_F(ConnectionParsing, Http_0_9_Multiple) {
     ASSERT_GE(rc, 0);
 
     ASSERT_EQ(1, htp_list_size(connp->conn->transactions));
-    ASSERT_TRUE(connp->conn->flags & HTP_CONN_HTTP_0_9_EXTRA);
 
     htp_tx_t *tx = (htp_tx_t *) htp_list_get(connp->conn->transactions, 0);
     ASSERT_TRUE(tx != NULL);

programming_language: C++