Skip to content

Commit 05a7711

Browse files
committed
http: do not search outside the header value
Header values in picohttp are not null-terminated so `strstr` would happily search outside the header value and exceed the length of the header value. This could lead to DoS in artifical circumstances which don't apply to fd in practice. There is always a null byte in memory _somewhere_ after the header value even if it is not actually part of the header value. This is because `fd_http_server_ws_frame`s are allocated after the request buffer that contains the headers and the ws_frames contain four bytes of padding that is zero, because the whole memory we're operating on, has been allocated with `mmap` anonymously which zeroes the memory QED.
1 parent 3be8509 commit 05a7711

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

src/waltz/http/fd_http_server.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,9 @@ read_conn_http( fd_http_server_t * http,
581581

582582
#if FD_HAS_ZSTD
583583
for( ulong i=0UL; i<num_headers; i++ ) {
584-
if( FD_LIKELY( headers[ i ].name_len==22UL && !strncasecmp( headers[ i ].name, "Sec-WebSocket-Protocol", 22UL ) && strstr( headers[ i ].value, "compress-zstd" ) ) ) {
584+
// Use `memmem` as the header is not guaranteed to be null terminated
585+
// `memmem` also matches "randomprefix_compress-zstd_randomsuffix" but that's fine, we don't want to fully parse the header value
586+
if( FD_LIKELY( headers[ i ].name_len==22UL && !strncasecmp( headers[ i ].name, "Sec-WebSocket-Protocol", 22UL ) && memmem( headers[ i ].value, headers[ i ].value_len, "compress-zstd", 14UL ) ) ) {
585587
compress_websocket = 1;
586588
}
587589
}

0 commit comments

Comments
 (0)