diff --git a/CHANGELOG b/CHANGELOG index 9414ef9b3..9b5fe9ed5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o Fixed a memory-consumption hang in Ncat's HTTP proxy code that affected both + connect and listen modes, reported by kumama_nui. + o Patched our included libssh2 source with upstream fixes for CVE-2025-15661, CVE-2026-7598, CVE-2026-55199, CVE-2026-55200, CVE-2026-58050, and CVE-2026-58051. The version number has been annotated as 1.11.1_NMAP1 diff --git a/ncat/http.c b/ncat/http.c index 570e67aa2..2057da723 100644 --- a/ncat/http.c +++ b/ncat/http.c @@ -117,6 +117,7 @@ char *socket_buffer_readline(struct socket_buffer *buf, size_t *n, size_t maxlen char *line; char *newline; size_t count; + const char *p; line = NULL; *n = 0; @@ -150,6 +151,17 @@ char *socket_buffer_readline(struct socket_buffer *buf, size_t *n, size_t maxlen *n += count; return NULL; } + /* Check for disallowed characters */ + p = buf->p + count - 2; + if (p >= buf->p && *p == '\r') + --p; + while (p >= buf->p) { + if (is_ctl_char(*p) && *p != '\t') { + free(line); + return NULL; + } + --p; + } line = (char *) safe_realloc(line, *n + count + 1); memcpy(line + *n, buf->p, count); @@ -975,22 +987,16 @@ int http_parse_header(struct http_header **result, const char *header) /* Copy the header field value until we hit a CRLF. */ p = q + 1; p = skip_lws(p); - for (;;) { - q = p; - while (*q != '\0' && !is_space_char(*q) && !is_crlf(q)) { - /* Section 2.2 of RFC 2616 disallows control characters. */ - if (iscntrl((int) (unsigned char) *q)) { - http_header_node_free(node); - return 400; - } - q++; + while (*p != '\0' && !is_crlf(p)) { + if (value_len > 0) { + /* Replace LWS with a single space. */ + strbuf_append_str(&node->value, &value_len, &value_offset, " "); } + q = strpbrk(p, " \t\r\n"); + if (!q) + q = p + strlen(p); strbuf_append(&node->value, &value_len, &value_offset, p, q - p); p = skip_lws(q); - if (is_crlf(p)) - break; - /* Replace LWS with a single space. */ - strbuf_append_str(&node->value, &value_len, &value_offset, " "); } *prev = node; prev = &node->next;