Repository: trafficserver Updated Branches: refs/heads/master 1f27b8407 -> 1cb87d281
TS-3793: Check the incoming header request length for HTTP/2 requests Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/1cb87d28 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/1cb87d28 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/1cb87d28 Branch: refs/heads/master Commit: 1cb87d281fef19c4e4e0a97c071fb0bcdad84365 Parents: 1f27b84 Author: Bryan Call <[email protected]> Authored: Thu Jul 23 19:42:25 2015 +0200 Committer: Bryan Call <[email protected]> Committed: Thu Jul 23 19:45:53 2015 +0200 ---------------------------------------------------------------------- proxy/http2/HTTP2.cc | 2 ++ proxy/http2/HTTP2.h | 1 + proxy/http2/Http2ConnectionState.cc | 14 ++++++++++++++ proxy/http2/Http2ConnectionState.h | 3 +++ 4 files changed, 20 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1cb87d28/proxy/http2/HTTP2.cc ---------------------------------------------------------------------- diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc index e7db7cb..6681308 100644 --- a/proxy/http2/HTTP2.cc +++ b/proxy/http2/HTTP2.cc @@ -762,6 +762,7 @@ uint32_t Http2::initial_window_size = 1048576; uint32_t Http2::max_frame_size = 16384; uint32_t Http2::header_table_size = 4096; uint32_t Http2::max_header_list_size = 4294967295; +uint32_t Http2::max_request_header_size = 131072; void Http2::init() @@ -771,6 +772,7 @@ Http2::init() REC_EstablishStaticConfigInt32U(max_frame_size, "proxy.config.http2.max_frame_size"); REC_EstablishStaticConfigInt32U(header_table_size, "proxy.config.http2.header_table_size"); REC_EstablishStaticConfigInt32U(max_header_list_size, "proxy.config.http2.max_header_list_size"); + REC_EstablishStaticConfigInt32U(max_request_header_size, "proxy.config.http.request_header_max_size"); // Setup statistics http2_rsb = RecAllocateRawStatBlock(static_cast<int>(HTTP2_N_STATS)); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1cb87d28/proxy/http2/HTTP2.h ---------------------------------------------------------------------- diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h index bdaf6f2..a577a15 100644 --- a/proxy/http2/HTTP2.h +++ b/proxy/http2/HTTP2.h @@ -314,6 +314,7 @@ public: static uint32_t max_frame_size; static uint32_t header_table_size; static uint32_t max_header_list_size; + static uint32_t max_request_header_size; static void init(); }; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1cb87d28/proxy/http2/Http2ConnectionState.cc ---------------------------------------------------------------------- diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc index c45ee32..eb24735 100644 --- a/proxy/http2/Http2ConnectionState.cc +++ b/proxy/http2/Http2ConnectionState.cc @@ -169,6 +169,13 @@ rcv_headers_frame(Http2ClientSession &cs, Http2ConnectionState &cstate, const Ht return HTTP2_ERROR_PROTOCOL_ERROR; } + // keep track of how many bytes we get in the frame + stream->request_header_length += payload_length; + if (stream->request_header_length > Http2::max_request_header_size) { + Error("HTTP/2 payload for headers exceeded: %u", stream->request_header_length); + return HTTP2_ERROR_PROTOCOL_ERROR; + } + // A receiver MUST treat the receipt of any other type of frame or // a frame on a different stream as a connection error of type PROTOCOL_ERROR. if (cstate.get_continued_id() != 0) { @@ -540,6 +547,13 @@ rcv_continuation_frame(Http2ClientSession &cs, Http2ConnectionState &cstate, con unsigned read_bytes = read_rcv_buffer(buf + remaining_bytes, sizeof(buf) - remaining_bytes, nbytes, frame); IOVec header_block_fragment = make_iovec(buf, read_bytes + remaining_bytes); + // keep track of how many bytes we get in the frame + stream->request_header_length += frame.header().length; + if (stream->request_header_length > Http2::max_request_header_size) { + Error("HTTP/2 payload for headers exceeded: %u", stream->request_header_length); + return HTTP2_ERROR_PROTOCOL_ERROR; + } + bool cont = nbytes < frame.header().length || !(frame.header().flags & HTTP2_FLAGS_HEADERS_END_HEADERS); int64_t decoded_bytes = stream->decode_request_header(header_block_fragment, *cstate.local_dynamic_table, cont); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1cb87d28/proxy/http2/Http2ConnectionState.h ---------------------------------------------------------------------- diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h index 9c05ab4..42f05f4 100644 --- a/proxy/http2/Http2ConnectionState.h +++ b/proxy/http2/Http2ConnectionState.h @@ -106,6 +106,7 @@ public: HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_STREAM_COUNT, _thread); _start_time = ink_hrtime(); _req_header.create(HTTP_TYPE_REQUEST); + request_header_length = 0; } ~Http2Stream() @@ -176,6 +177,8 @@ public: LINK(Http2Stream, link); + uint32_t request_header_length; + private: ink_hrtime _start_time; EThread *_thread;
