From a40a19a738f3916a917efc51a46d9e39ececd27e Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Tue, 3 Mar 2026 12:55:24 +0100 Subject: [PATCH] Add HTTP Content-Length upper-bound check Content-Length header value stored in hsock->contentlength without upper-bound check. Define MAX_HTTP_CONTENT_LENGTH (1GB) and reject responses exceeding it before allocation in both psync_http_connect and psync_http_request functions. Prevents DoS via maliciously large Content-Length. Fixes GH #240 --- pclsync/pnetlibs.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/pclsync/pnetlibs.c b/pclsync/pnetlibs.c index fa1b241..aeb9786 100644 --- a/pclsync/pnetlibs.c +++ b/pclsync/pnetlibs.c @@ -52,6 +52,8 @@ #include "ptimer.h" #include "ptree.h" +#define MAX_HTTP_CONTENT_LENGTH (1024ULL * 1024 * 1024) // 1GB + // required by psync_send_debug extern PSYNC_THREAD const char *psync_thread_name; @@ -912,9 +914,15 @@ cont: } *ptr = 0; /* pdbg_logf(D_NOTICE, "key=%s, value=%s", key, val);*/ - if (!memcmp(key, "content-length", 14)) + if (!memcmp(key, "content-length", 14)) { clen = putil_ato64(val); - else if (!memcmp(key, "keep-alive", 10) && !memcmp(val, "timeout=", 8)) + if (clen > MAX_HTTP_CONTENT_LENGTH) { + pdbg_logf(D_WARNING, "Content-Length %llu exceeds limit %llu", + (unsigned long long)clen, + (unsigned long long)MAX_HTTP_CONTENT_LENGTH); + goto err1; + } + } else if (!memcmp(key, "keep-alive", 10) && !memcmp(val, "timeout=", 8)) keepalive = putil_ato32(val + 8); key = ptr + 1; isval = 0; @@ -1410,9 +1418,15 @@ cont: } *ptr = 0; /* pdbg_logf(D_NOTICE, "key=%s, value=%s", key, val);*/ - if (!memcmp(key, "content-length", 14)) + if (!memcmp(key, "content-length", 14)) { clen = putil_ato64(val); - else if (!memcmp(key, "keep-alive", 10) && !memcmp(val, "timeout=", 8)) + if (clen > MAX_HTTP_CONTENT_LENGTH) { + pdbg_logf(D_WARNING, "Content-Length %llu exceeds limit %llu", + (unsigned long long)clen, + (unsigned long long)MAX_HTTP_CONTENT_LENGTH); + goto err0; + } + } else if (!memcmp(key, "keep-alive", 10) && !memcmp(val, "timeout=", 8)) keepalive = putil_ato32(val + 8); key = ptr + 1; isval = 0;