mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-02 05:22:46 +07:00
Reject malformed chunk-size in chunked decoder
strtoul silently accepts a leading "-" and wraps via unsigned arithmetic, so chunk-size "-2" produced ULONG_MAX-1, bypassing the ULONG_MAX guard and letting a client drive the server toward unbounded allocation. Replace strtoul with a manual hex parser that requires at least one hex digit, detects size_t overflow per digit, and accepts only chunk-ext or end-of-line after the digits (RFC 9112 §7.1).
This commit is contained in:
@@ -5146,6 +5146,39 @@ TEST_F(ServerTest, CaseInsensitiveTransferEncoding) {
|
||||
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||
}
|
||||
|
||||
// GHSA-h6wq-j5mv-f3q8: the server must reject malformed chunk-size lines
|
||||
// rather than treat them as valid lengths.
|
||||
template <typename ClientT>
|
||||
static void expect_chunked_body_rejected(ClientT &cli, const char *body) {
|
||||
Request req;
|
||||
req.method = "POST";
|
||||
req.path = "/chunked";
|
||||
|
||||
std::string host_and_port;
|
||||
host_and_port += HOST;
|
||||
host_and_port += ":";
|
||||
host_and_port += std::to_string(PORT);
|
||||
|
||||
req.headers.emplace("Host", host_and_port.c_str());
|
||||
req.headers.emplace("Content-Length", "0");
|
||||
req.headers.emplace("Transfer-Encoding", "chunked");
|
||||
req.body = body;
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
auto error = Error::Success;
|
||||
ASSERT_TRUE(cli.send(req, *res, error));
|
||||
EXPECT_EQ(StatusCode::BadRequest_400, res->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, RejectsNegativeChunkSize) {
|
||||
expect_chunked_body_rejected(cli_, "-2\r\nAAAA\r\n0\r\n\r\n");
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, RejectsChunkSizeWithLeadingPlus) {
|
||||
expect_chunked_body_rejected(
|
||||
cli_, "+4\r\ndech\r\nf\r\nunked post body\r\n0\r\n\r\n");
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, GetStreamed2) {
|
||||
auto res = cli_.Get("/streamed", {{make_range_header({{2, 3}})}});
|
||||
ASSERT_TRUE(res);
|
||||
|
||||
Reference in New Issue
Block a user