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
This commit is contained in:
Levi Neely 2026-03-03 12:55:24 +01:00
parent c73bcaf871
commit a40a19a738
1 changed files with 18 additions and 4 deletions

View File

@ -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;