mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add test case http2_cancel_flood in security suite
This commit is contained in:
parent
80b2a5b86a
commit
23eff8ce69
1 changed files with 44 additions and 0 deletions
|
@ -39,6 +39,7 @@ groups() ->
|
||||||
http2_empty_frame_flooding_push_promise,
|
http2_empty_frame_flooding_push_promise,
|
||||||
http2_ping_flood,
|
http2_ping_flood,
|
||||||
http2_reset_flood,
|
http2_reset_flood,
|
||||||
|
http2_cancel_flood,
|
||||||
http2_settings_flood,
|
http2_settings_flood,
|
||||||
http2_zero_length_header_leak
|
http2_zero_length_header_leak
|
||||||
],
|
],
|
||||||
|
@ -72,6 +73,7 @@ init_dispatch(_) ->
|
||||||
cowboy_router:compile([{"localhost", [
|
cowboy_router:compile([{"localhost", [
|
||||||
{"/", hello_h, []},
|
{"/", hello_h, []},
|
||||||
{"/echo/:key", echo_h, []},
|
{"/echo/:key", echo_h, []},
|
||||||
|
{"/delay_hello", delay_hello_h, 1000},
|
||||||
{"/long_polling", long_polling_h, []},
|
{"/long_polling", long_polling_h, []},
|
||||||
{"/resp/:key[/:arg]", resp_h, []}
|
{"/resp/:key[/:arg]", resp_h, []}
|
||||||
]}]).
|
]}]).
|
||||||
|
@ -229,6 +231,48 @@ http2_reset_flood(Config) ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
http2_cancel_flood(Config) ->
|
||||||
|
doc("Confirm that Cowboy detects the rapid reset attack. (CVE-2023-44487)"),
|
||||||
|
http2_cancel_flood_helper(Config, 1, 500),
|
||||||
|
http2_cancel_flood_helper(Config, 10, 50),
|
||||||
|
http2_cancel_flood_helper(Config, 500, 1),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
http2_cancel_flood_helper(Config, NumStreamsPerBatch, NumBatches) ->
|
||||||
|
{ok, Socket} = rfc7540_SUITE:do_handshake(Config),
|
||||||
|
{HeadersBlock, _} = cow_hpack:encode([
|
||||||
|
{<<":method">>, <<"GET">>},
|
||||||
|
{<<":scheme">>, <<"http">>},
|
||||||
|
{<<":authority">>, <<"localhost">>}, %% @todo Correct port number.
|
||||||
|
{<<":path">>, <<"/delay_hello">>}
|
||||||
|
]),
|
||||||
|
AllStreamIDs = lists:seq(1, NumBatches * NumStreamsPerBatch * 2, 2),
|
||||||
|
ct:pal("http2_cancel_flood_helper(..., ~p, ~p)", [NumStreamsPerBatch, NumBatches]),
|
||||||
|
_ = lists:foldl(
|
||||||
|
fun (_BatchNumber, AvailableStreamIDs) ->
|
||||||
|
%% Take a bunch of IDs from the available stream IDs.
|
||||||
|
%% Send HEADERS for all these and then cancel them.
|
||||||
|
{IDs, RemainingStreamIDs} = lists:split(NumStreamsPerBatch, AvailableStreamIDs),
|
||||||
|
_ = gen_tcp:send(Socket, [cow_http2:headers(ID, fin, HeadersBlock) || ID <- IDs]),
|
||||||
|
_ = gen_tcp:send(Socket, [<<4:24, 3:8, 0:8, ID:32, 8:32>> || ID <- IDs]),
|
||||||
|
RemainingStreamIDs
|
||||||
|
end,
|
||||||
|
AllStreamIDs,
|
||||||
|
lists:seq(1, NumBatches, 1)),
|
||||||
|
%% When Cowboy detects a flood it must close the connection.
|
||||||
|
case gen_tcp:recv(Socket, 9, 6000) of
|
||||||
|
{ok, <<_:24, 7:8, 0:8, 0:32>>} ->
|
||||||
|
%% GOAWAY with error code 11 = enhance your calm
|
||||||
|
{ok, <<_LastStreamId:32, ErrorCode:32>>} =
|
||||||
|
gen_tcp:recv(Socket, 8, 1000),
|
||||||
|
11 = ErrorCode, %% ENHANCE_YOUR_CALM
|
||||||
|
ok;
|
||||||
|
%% We also accept the connection being closed immediately,
|
||||||
|
%% which may happen because we send the GOAWAY right before closing.
|
||||||
|
{error, closed} ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
%% @todo If we ever implement the PRIORITY mechanism, this test should
|
%% @todo If we ever implement the PRIORITY mechanism, this test should
|
||||||
%% be implemented as well. CVE-2019-9513 https://www.kb.cert.org/vuls/id/605641/
|
%% be implemented as well. CVE-2019-9513 https://www.kb.cert.org/vuls/id/605641/
|
||||||
%% http2_resource_loop
|
%% http2_resource_loop
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue