Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/inets/doc/guides/hardening.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,22 +229,22 @@ or

### Request Size Limits

Several size limits default to `nolimit`, which allows arbitrarily large
Before OTP 30 several size limits default to `nolimit`, which allows arbitrarily large
requests that can exhaust memory. Set explicit limits:

```erlang
[{max_uri_size, 8192}, %% 8 KB URI limit
[{max_uri_size, 8192}, %% 8 KB URI limit (default since OTP 30)
{max_header_size, 10240}, %% 10 KB (already the default)
{max_body_size, 10_485_760}, %% 10 MB body limit
{max_content_length, 10_485_760}] %% 10 MB Content-Length check
```

- **[`max_uri_size`](`m:httpd#prop_max_uri`)** - Maximum URI length in bytes. Default: `nolimit`.
- **[`max_uri_size`](`m:httpd#prop_max_uri`)** - Maximum URI length in bytes. Default: `8192` (8 KB).

- **[`max_header_size`](`m:httpd#prop_max_header_size`)** - Maximum total header size. Default: `10240` (10 KB).

- **[`max_body_size`](`m:httpd#prop_max_body_size`)** - Maximum received body size during parsing. Default:
`nolimit`.
`100_000_000` (100 MB).

- **[`max_content_length`](`m:httpd#prop_max_content_length`)** - Rejects requests whose `Content-Length` header
exceeds this value with a 413 response, before reading the body. Default:
Expand All @@ -253,7 +253,7 @@ requests that can exhaust memory. Set explicit limits:
- **[`max_client_body_chunk`](`m:httpd#max_client_body_chunk`)** - When handling large PUT or POST bodies via
`mod_esi`, setting this option enforces chunked delivery to the ESI
callback. This prevents the server from buffering the entire request body
in memory, which could be exploited to cause memory exhaustion.
in memory, which could be exploited to cause memory exhaustion. Default: `nolimit`.

> #### Note {: .info }
>
Expand Down
6 changes: 3 additions & 3 deletions lib/inets/src/http_lib/http_internal.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@

-include_lib("inets/src/inets_app/inets_internal.hrl").

-define(HTTP_MAX_BODY_SIZE, nolimit).
-define(HTTP_MAX_BODY_SIZE, ?HTTP_MAX_CONTENT_LENGTH). %% 100 MB, same as max-content length
-define(HTTP_MAX_HEADER_SIZE, 10240).
-define(HTTP_MAX_URI_SIZE, nolimit).
-define(HTTP_MAX_URI_SIZE, 8192).
-define(HTTP_MAX_VERSION_STRING, 8).
-define(HTTP_MAX_METHOD_STRING, 20).
-define(HTTP_MAX_CONTENT_LENGTH, 100000000).
-define(HTTP_MAX_CONTENT_LENGTH, 100000000). %% 100 MB

-define(DATA_20MB, <<0:16#A000000>>).

Expand Down
5 changes: 3 additions & 2 deletions lib/inets/src/http_server/httpd.erl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ property list.
client before closing the connection. Default is `150`.

- [](){: #prop_max_body_size } **`{max_body_size, integer()}`**
Limits the size of the message body of an HTTP request. Default is no limit.
Limits the size of the message body of an HTTP request. Default is `100000000` (100
MB).

- [](){: #prop_max_clients } **`{max_clients, integer()}`**
Limits the number of simultaneous requests that can be supported. Default is
Expand All @@ -187,7 +188,7 @@ property list.
MB).

- [](){: #prop_max_uri } **`{max_uri_size, integer()}`**
Limits the size of the HTTP request URI. Default is no limit.
Limits the size of the HTTP request URI. Default is `8192` (8 KB).

- [](){: #prop_max_keep_alive_req } **`{max_keep_alive_request, integer()}`**
The number of requests that a client can do on one connection. When the server
Expand Down
6 changes: 6 additions & 0 deletions lib/inets/src/http_server/httpd_conf.erl
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ validate_config_params([{max_content_length, Value} | Rest])
validate_config_params([{max_content_length, Value} | _]) ->
throw({max_content_length, Value});

validate_config_params([{max_uri_size, Value} | Rest])
when is_integer(Value) andalso (Value > 0) ->
validate_config_params(Rest);
validate_config_params([{max_uri_size, Value} | _]) ->
throw({max_uri_size, Value});

validate_config_params([{server_name, Value} | Rest])
when is_list(Value) ->
validate_config_params(Rest);
Expand Down
6 changes: 2 additions & 4 deletions lib/inets/src/http_server/httpd_request.erl
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@ parse_method(_, _, _, Max, _, _) ->
%% will be able to handle it.
{error, {size_error, Max, 413, "Method unreasonably long"}, default_version()}.

parse_uri(_, _, Current, MaxURI, _, _)
when (Current > MaxURI) andalso (MaxURI =/= nolimit) ->
parse_uri(_, _, Current, MaxURI, _, _) when Current > MaxURI ->
%% We do not know the version of the client as it comes after the
%% uri send the lowest version in the response so that the client
%% will be able to handle it.
Expand Down Expand Up @@ -180,8 +179,7 @@ parse_version(<<Octet, Rest/binary>>, Version, Current, Max, Options, Result) w
parse_version(_, _, _, Max,_,_) ->
{error, {size_error, Max, 413, "Version string unreasonably long"}, default_version()}.

parse_headers(_, _, _, Current, Max, _, Result)
when Max =/= nolimit andalso Current > Max ->
parse_headers(_, _, _, Current, Max, _, Result) when Current > Max ->
HttpVersion = lists:nth(3, lists:reverse(Result)),
{error, {size_error, Max, 413, "Headers unreasonably long"}, HttpVersion};

Expand Down
6 changes: 3 additions & 3 deletions lib/inets/src/http_server/httpd_request_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ handle_body(#state{headers = Headers, body = Body,
_ ->
Length = list_to_integer(Headers#http_request_h.'content-length'),
MaxChunk = max_client_body_chunk(ConfigDB),
case Length =< MaxBodySize orelse MaxBodySize == nolimit of
case Length =< MaxBodySize of
true ->
case httpd_request:body_chunk_first(Body, Length, MaxChunk) of
%% This is the case that the we need more data to complete
Expand Down Expand Up @@ -572,7 +572,7 @@ handle_expect(#state{headers = Headers, mod =
MaxBodySize) ->
Length = list_to_integer(Headers#http_request_h.'content-length'),
case expect(Headers, ModData#mod.http_version, ConfigDB) of
continue when (MaxBodySize > Length) orelse (MaxBodySize =:= nolimit) ->
continue when MaxBodySize > Length ->
httpd_response:send_status(ModData, 100, ""),
ok;
continue when MaxBodySize < Length ->
Expand Down Expand Up @@ -762,7 +762,7 @@ max_uri_size(ConfigDB) ->
httpd_util:lookup(ConfigDB, max_uri_size, ?HTTP_MAX_URI_SIZE).

max_body_size(ConfigDB) ->
httpd_util:lookup(ConfigDB, max_body_size, nolimit).
httpd_util:lookup(ConfigDB, max_body_size, ?HTTP_MAX_BODY_SIZE).

max_keep_alive_request(ConfigDB) ->
httpd_util:lookup(ConfigDB, max_keep_alive_request, infinity).
Expand Down
Loading