CVE-2024-28871: Insufficient Information (NVD-CWE-noinfo)
value: 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.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-04-04T15:15Z
Repository: https://github.com/OISF/libhtp
Language: C++
Files changed: htp/htp_request.c, test/test_main.cpp
Commit date: 2024-01-23 11:31:37 +0100
Commit message: 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

Diff: diff --git a/htp/htp_request.c b/htp/htp_request.c
index f802287a..57e5d0e2 100644
--- a/htp/htp_request.c
+++ b/htp/htp_request.c
@@ -742,25 +742,19 @@ htp_status_t htp_connp_REQ_PROTOCOL(htp_connp_t *connp) {
         connp->in_state = htp_connp_REQ_HEADERS;
         connp->in_tx->request_progress = HTP_REQUEST_HEADERS;
     } 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++;
         }
         // We're done with this request.
         connp->in_state = htp_connp_REQ_FINALIZE;
diff --git a/test/test_main.cpp b/test/test_main.cpp
index 4e3e7760..73b86868 100644
--- a/test/test_main.cpp
+++ b/test/test_main.cpp
@@ -556,11 +556,10 @@ TEST_F(ConnectionParsing, Http11HostMissing) {
 TEST_F(ConnectionParsing, Http_0_9_Multiple) {
     int rc = test_run(home, "23-http09-multiple.t", cfg, &connp);
     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);
 }
 

Vulnerable code:         int afterspaces = 0;
            if (connp->in_current_data[pos] == ':') {
            } 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;
    ASSERT_TRUE(connp->conn->flags & HTP_CONN_HTTP_0_9_EXTRA);
Fixed code:             if (!htp_is_space(connp->in_current_data[pos])) {