Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9d4b426

Browse files
Merge pull request #2844 from martinhsv/v2/master
Support configurable limit on number of arguments processed
2 parents ac52086 + 0981b32 commit 9d4b426

File tree

6 files changed

+109
-4
lines changed

6 files changed

+109
-4
lines changed

‎CHANGES‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
DD mmm YYYY - 2.9.x (to be released)
22
-------------------
33

4+
* Support configurable limit on number of arguments processed
5+
[Issue #2844 - @jleproust, @martinhsv]
46
* Silence compiler warning about discarded const
57
[Issue #2843 - @Steve8291, @martinhsv]
68
* Support for JIT option for PCRE2

‎apache2/apache2_config.c‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void *create_directory_config(apr_pool_t *mp, char *path)
5454
dcfg->reqbody_limit = NOT_SET;
5555
dcfg->reqbody_no_files_limit = NOT_SET;
5656
dcfg->reqbody_json_depth_limit = NOT_SET;
57+
dcfg->arguments_limit = NOT_SET;
5758
dcfg->resbody_access = NOT_SET;
5859

5960
dcfg->debuglog_name = NOT_SET_P;
@@ -338,6 +339,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
338339
? parent->reqbody_no_files_limit : child->reqbody_no_files_limit);
339340
merged->reqbody_json_depth_limit = (child->reqbody_json_depth_limit == NOT_SET
340341
? parent->reqbody_json_depth_limit : child->reqbody_json_depth_limit);
342+
merged->arguments_limit = (child->arguments_limit == NOT_SET
343+
? parent->arguments_limit : child->arguments_limit);
341344
merged->resbody_access = (child->resbody_access == NOT_SET
342345
? parent->resbody_access : child->resbody_access);
343346

@@ -655,6 +658,7 @@ void init_directory_config(directory_config *dcfg)
655658
if (dcfg->reqbody_limit == NOT_SET) dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
656659
if (dcfg->reqbody_no_files_limit == NOT_SET) dcfg->reqbody_no_files_limit = REQUEST_BODY_NO_FILES_DEFAULT_LIMIT;
657660
if (dcfg->reqbody_json_depth_limit == NOT_SET) dcfg->reqbody_json_depth_limit = REQUEST_BODY_JSON_DEPTH_DEFAULT_LIMIT;
661+
if (dcfg->arguments_limit == NOT_SET) dcfg->arguments_limit = ARGUMENTS_LIMIT;
658662
if (dcfg->resbody_access == NOT_SET) dcfg->resbody_access = 0;
659663
if (dcfg->of_limit == NOT_SET) dcfg->of_limit = RESPONSE_BODY_DEFAULT_LIMIT;
660664
if (dcfg->if_limit_action == NOT_SET) dcfg->if_limit_action = REQUEST_BODY_LIMIT_ACTION_REJECT;
@@ -1955,6 +1959,24 @@ static const char *cmd_request_body_json_depth_limit(cmd_parms *cmd, void *_dcfg
19551959
return NULL;
19561960
}
19571961

1962+
static const char *cmd_arguments_limit(cmd_parms *cmd, void *_dcfg,
1963+
const char *p1)
1964+
{
1965+
directory_config *dcfg = (directory_config *)_dcfg;
1966+
long int limit;
1967+
1968+
if (dcfg == NULL) return NULL;
1969+
1970+
limit = strtol(p1, NULL, 10);
1971+
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
1972+
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecArgumentsLimit: %s", p1);
1973+
}
1974+
1975+
dcfg->arguments_limit = limit;
1976+
1977+
return NULL;
1978+
}
1979+
19581980
static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg,
19591981
const char *p1)
19601982
{
@@ -3596,6 +3618,14 @@ const command_rec module_directives[] = {
35963618
"maximum request body JSON parsing depth ModSecurity will accept."
35973619
),
35983620

3621+
AP_INIT_TAKE1 (
3622+
"SecArgumentsLimit",
3623+
cmd_arguments_limit,
3624+
NULL,
3625+
CMD_SCOPE_ANY,
3626+
"maximum number of ARGS that ModSecurity will accept."
3627+
),
3628+
35993629
AP_INIT_TAKE1 (
36003630
"SecRequestEncoding",
36013631
cmd_request_encoding,

‎apache2/modsecurity.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
3-
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
3+
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
44
*
55
* You may not use this file except in compliance with
66
* the License. You may obtain a copy of the License at
@@ -96,6 +96,7 @@ typedef struct msc_parm msc_parm;
9696
#define REQUEST_BODY_DEFAULT_LIMIT 134217728
9797
#define REQUEST_BODY_NO_FILES_DEFAULT_LIMIT 1048576
9898
#define REQUEST_BODY_JSON_DEPTH_DEFAULT_LIMIT 10000
99+
#define ARGUMENTS_LIMIT 1000
99100
#define RESPONSE_BODY_DEFAULT_LIMIT 524288
100101
#define RESPONSE_BODY_HARD_LIMIT 1073741824L
101102

@@ -500,6 +501,7 @@ struct directory_config {
500501
long int reqbody_limit;
501502
long int reqbody_no_files_limit;
502503
long int reqbody_json_depth_limit;
504+
long int arguments_limit;
503505
int resbody_access;
504506

505507
long int of_limit;

‎apache2/msc_json.c‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
3-
* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
3+
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
44
*
55
* You may not use this file except in compliance with
66
* the License. You may obtain a copy of the License at
@@ -57,6 +57,15 @@ int json_add_argument(modsec_rec *msr, const char *value, unsigned length)
5757
msr_log(msr, 9, "Adding JSON argument '%s' with value '%s'",
5858
arg->name, arg->value);
5959
}
60+
if (apr_table_elts(msr->arguments)->nelts >= msr->txcfg->arguments_limit) {
61+
if (msr->txcfg->debuglog_level >= 4) {
62+
msr_log(msr, 4, "Skipping request argument, over limit (%s): name \"%s\", value \"%s\"",
63+
arg->origin, log_escape_ex(msr->mp, arg->name, arg->name_len),
64+
log_escape_ex(msr->mp, arg->value, arg->value_len));
65+
}
66+
msr->msc_reqbody_error = 1;
67+
return 0;
68+
}
6069

6170
apr_table_addn(msr->arguments,
6271
log_escape_nq_ex(msr->mp, arg->name, arg->name_len), (void *) arg);

‎apache2/msc_parsers.c‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
3-
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
3+
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
44
*
55
* You may not use this file except in compliance with
66
* the License. You may obtain a copy of the License at
@@ -346,6 +346,21 @@ void add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg)
346346
log_escape_ex(msr->mp, arg->value, arg->value_len));
347347
}
348348

349-
apr_table_addn(arguments, log_escape_nq_ex(msr->mp, arg->name, arg->name_len), (void *)arg);
349+
if (apr_table_elts(arguments)->nelts >= msr->txcfg->arguments_limit) {
350+
if (msr->txcfg->debuglog_level >= 4) {
351+
msr_log(msr, 4, "Skipping request argument, over limit (%s): name \"%s\", value \"%s\"",
352+
arg->origin, log_escape_ex(msr->mp, arg->name, arg->name_len),
353+
log_escape_ex(msr->mp, arg->value, arg->value_len));
354+
}
355+
if (msr->msc_reqbody_error != 1) {
356+
char *error_msg = apr_psprintf(msr->mp, "SecArgumentsLimit exceeded");
357+
msr->msc_reqbody_error = 1;
358+
if (error_msg != NULL) {
359+
msr->msc_reqbody_error_msg = error_msg;
360+
}
361+
}
362+
} else {
363+
apr_table_addn(arguments, log_escape_nq_ex(msr->mp, arg->name, arg->name_len), (void *)arg);
364+
}
350365
}
351366

‎tests/regression/config/10-request-directives.t‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,3 +703,50 @@
703703
),
704704
},
705705

706+
# SecArgumentsLimit
707+
{
708+
type => "config",
709+
comment => "SecArgumentsLimit (pos)",
710+
conf => qq(
711+
SecRuleEngine On
712+
SecRequestBodyAccess On
713+
SecArgumentsLimit 5
714+
SecRule REQBODY_ERROR "!\@eq 0" "id:'500232',phase:2,log,deny,status:403,msg:'Failed to parse request body'"
715+
),
716+
match_log => {
717+
error => [ qr/Access denied with code 403 /, 1 ],
718+
},
719+
match_response => {
720+
status => qr/^403$/,
721+
},
722+
request => new HTTP::Request(
723+
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
724+
[
725+
"Content-Type" => "application/x-www-form-urlencoded",
726+
],
727+
"a=1&b=2&c=3&d=4&e=5&f=6",
728+
),
729+
},
730+
{
731+
type => "config",
732+
comment => "SecArgumentsLimit (neg)",
733+
conf => qq(
734+
SecRuleEngine On
735+
SecRequestBodyAccess On
736+
SecArgumentsLimit 5
737+
SecRule REQBODY_ERROR "!\@eq 0" "id:'500233',phase:2,log,deny,status:403,msg:'Failed to parse request body'"
738+
),
739+
match_log => {
740+
},
741+
match_response => {
742+
status => qr/^200$/,
743+
},
744+
request => new HTTP::Request(
745+
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
746+
[
747+
"Content-Type" => "application/x-www-form-urlencoded",
748+
],
749+
"a=1&b=2&c=3&d=4&e=5",
750+
),
751+
},
752+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /