mirror of https://github.com/Icinga/icinga2.git
Limit HTTP body size
This commit is contained in:
parent
3fe818b44b
commit
4b77afedcd
|
@ -201,23 +201,27 @@ The [regex function](18-library-reference.md#global-functions-regex) is availabl
|
|||
|
||||
More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter.
|
||||
|
||||
Note that the permissions a API user has also specify the max body size of their requests.
|
||||
A API user with `*` permissions is allowed to send 512 MB.
|
||||
|
||||
|
||||
Available permissions for specific URL endpoints:
|
||||
|
||||
Permissions | URL Endpoint | Supports Filters
|
||||
------------------------------|---------------|-----------------
|
||||
actions/<action> | /v1/actions | Yes
|
||||
config/query | /v1/config | No
|
||||
config/modify | /v1/config | No
|
||||
console | /v1/console | No
|
||||
events/<type> | /v1/events | No
|
||||
objects/query/<type> | /v1/objects | Yes
|
||||
objects/create/<type> | /v1/objects | No
|
||||
objects/modify/<type> | /v1/objects | Yes
|
||||
objects/delete/<type> | /v1/objects | Yes
|
||||
status/query | /v1/status | Yes
|
||||
templates/<type> | /v1/templates | Yes
|
||||
types | /v1/types | Yes
|
||||
variables | /v1/variables | Yes
|
||||
Permissions | URL Endpoint | Supports Filters | Max Body Size in MB
|
||||
------------------------------|---------------|-------------------|---------------------
|
||||
actions/<action> | /v1/actions | Yes | 1
|
||||
config/query | /v1/config | No | 1
|
||||
config/modify | /v1/config | No | 512
|
||||
console | /v1/console | No | 512
|
||||
events/<type> | /v1/events | No | 1
|
||||
objects/query/<type> | /v1/objects | Yes | 1
|
||||
objects/create/<type> | /v1/objects | No | 512
|
||||
objects/modify/<type> | /v1/objects | Yes | 512
|
||||
objects/delete/<type> | /v1/objects | Yes | 512
|
||||
status/query | /v1/status | Yes | 1
|
||||
templates/<type> | /v1/templates | Yes | 1
|
||||
types | /v1/types | Yes | 1
|
||||
variables | /v1/variables | Yes | 1
|
||||
|
||||
The required actions or types can be replaced by using a wildcard match ("\*").
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ ApiUser::Ptr ApiUser::GetByClientCN(const String& cn)
|
|||
return ApiUser::Ptr();
|
||||
}
|
||||
|
||||
ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header) {
|
||||
ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header)
|
||||
{
|
||||
String::SizeType pos = auth_header.FindFirstOf(" ");
|
||||
String username, password;
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ void HttpServerConnection::Disconnect(void)
|
|||
|
||||
bool HttpServerConnection::ProcessMessage(void)
|
||||
{
|
||||
|
||||
bool res;
|
||||
HttpResponse response(m_Stream, m_CurrentRequest);
|
||||
|
||||
|
@ -186,6 +187,16 @@ bool HttpServerConnection::ProcessMessage(void)
|
|||
|
||||
bool HttpServerConnection::ManageHeaders(HttpResponse& response)
|
||||
{
|
||||
static const size_t defaultContentLengthLimit = 1 * 1028 * 1028;
|
||||
static const Dictionary::Ptr specialContentLengthLimits = new Dictionary({
|
||||
{"*", 512 * 1028 * 1028},
|
||||
{"config/modify", 512 * 1028 * 1028},
|
||||
{"console", 512 * 1028 * 1028},
|
||||
{"objects/create", 512 * 1028 * 1028},
|
||||
{"objects/modify", 512 * 1028 * 1028},
|
||||
{"objects/delete", 512 * 1028 * 1028}
|
||||
});
|
||||
|
||||
if (m_CurrentRequest.Headers->Get("expect") == "100-continue") {
|
||||
String continueResponse = "HTTP/1.1 100 Continue\r\n\r\n";
|
||||
m_Stream->Write(continueResponse.CStr(), continueResponse.GetLength());
|
||||
|
@ -276,6 +287,29 @@ bool HttpServerConnection::ManageHeaders(HttpResponse& response)
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t maxSize = defaultContentLengthLimit;
|
||||
|
||||
Array::Ptr permissions = m_AuthenticatedUser->GetPermissions();
|
||||
ObjectLock olock(permissions);
|
||||
|
||||
for (const Value& permission : permissions) {
|
||||
std::vector<String> permissionParts = String(permission).Split("/");
|
||||
String permissionPath = permissionParts[0] + (permissionParts.size() > 1 ? "/" + permissionParts[1] : "");
|
||||
int size = specialContentLengthLimits->Get(permissionPath);
|
||||
maxSize = size > maxSize ? size : maxSize;
|
||||
}
|
||||
|
||||
size_t contentLength = m_CurrentRequest.Headers->Get("content-length");
|
||||
|
||||
if (contentLength > maxSize) {
|
||||
response.SetStatus(400, "Bad Request");
|
||||
String msg = String("<h1>Content length exceeded maximum</h1>");
|
||||
response.WriteBody(msg.CStr(), msg.GetLength());
|
||||
response.Finish();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue