mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 13:26:01 +03:00
Support configurable limit on number of arguments processed
This commit is contained in:
parent
4e9ba44d03
commit
f57265a3e2
2
CHANGES
2
CHANGES
@ -13,6 +13,8 @@ v3.x.y - YYYY-MMM-DD (to be released)
|
||||
v3.0.4 - 2020-Jan-13
|
||||
--------------------
|
||||
|
||||
- Support configurable limit on number of arguments processed
|
||||
[@jleproust, @martinhsv]
|
||||
- Fix: audit log data omitted when nolog,auditlog
|
||||
[@martinhsv]
|
||||
- Fix: ModSecurity 3.x inspectFile operator does not pass
|
||||
|
@ -384,6 +384,7 @@ class RulesProperties {
|
||||
from->m_tmpSaveUploadedFiles,
|
||||
PropertyNotSetConfigBoolean);
|
||||
|
||||
to->m_argumentsLimit.merge(&from->m_argumentsLimit);
|
||||
to->m_requestBodyLimit.merge(&from->m_requestBodyLimit);
|
||||
to->m_responseBodyLimit.merge(&from->m_responseBodyLimit);
|
||||
|
||||
@ -531,6 +532,7 @@ class RulesProperties {
|
||||
ConfigBoolean m_secXMLExternalEntity;
|
||||
ConfigBoolean m_tmpSaveUploadedFiles;
|
||||
ConfigBoolean m_uploadKeepFiles;
|
||||
ConfigDouble m_argumentsLimit;
|
||||
ConfigDouble m_requestBodyLimit;
|
||||
ConfigDouble m_requestBodyNoFilesLimit;
|
||||
ConfigDouble m_responseBodyLimit;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -601,6 +601,7 @@ using namespace modsecurity::operators;
|
||||
CONFIG_SEC_CONN_R_STATE_LIMIT "CONFIG_SEC_CONN_R_STATE_LIMIT"
|
||||
CONFIG_SEC_CONN_W_STATE_LIMIT "CONFIG_SEC_CONN_W_STATE_LIMIT"
|
||||
CONFIG_SEC_SENSOR_ID "CONFIG_SEC_SENSOR_ID"
|
||||
CONFIG_DIR_ARGS_LIMIT "CONFIG_DIR_ARGS_LIMIT"
|
||||
CONFIG_DIR_REQ_BODY "CONFIG_DIR_REQ_BODY"
|
||||
CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT"
|
||||
CONFIG_DIR_REQ_BODY_LIMIT "CONFIG_DIR_REQ_BODY_LIMIT"
|
||||
@ -1553,6 +1554,11 @@ expression:
|
||||
YYERROR;
|
||||
#endif // WITH_GEOIP
|
||||
}
|
||||
| CONFIG_DIR_ARGS_LIMIT
|
||||
{
|
||||
driver.m_argumentsLimit.m_set = true;
|
||||
driver.m_argumentsLimit.m_value = atoi($1.c_str());
|
||||
}
|
||||
/* Body limits */
|
||||
| CONFIG_DIR_REQ_BODY_LIMIT
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -359,6 +359,7 @@ CONFIG_SEC_STREAM_IN_BODY_INSPECTION (?i:SecStreamInBodyInspection)
|
||||
CONFIG_SEC_STREAM_OUT_BODY_INSPECTION (?i:SecStreamOutBodyInspection)
|
||||
CONFIG_DIR_PCRE_MATCH_LIMIT (?i:SecPcreMatchLimit)
|
||||
CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION (?i:SecPcreMatchLimitRecursion)
|
||||
CONFIG_DIR_ARGS_LIMIT (?i:SecArgumentsLimit)
|
||||
CONFIG_DIR_REQ_BODY (?i:SecRequestBodyAccess)
|
||||
CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT (?i:SecRequestBodyInMemoryLimit)
|
||||
CONFIG_DIR_REQ_BODY_LIMIT (?i:SecRequestBodyLimit)
|
||||
@ -758,13 +759,17 @@ EQUALS_MINUS (?i:=\-)
|
||||
{CONFIG_DIR_AUDIT_STS}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }
|
||||
{CONFIG_DIR_AUDIT_STS}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }
|
||||
{CONFIG_DIR_AUDIT_TPE} { return p::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); }
|
||||
|
||||
|
||||
{CONFIG_DIR_DEBUG_LOG}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_DEBUG_LOG}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }
|
||||
{CONFIG_DIR_DEBUG_LVL}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_GEO_DB}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_PCRE_MATCH_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_ARGS_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_ARGS_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
|
||||
{CONFIG_DIR_REQ_BODY_LIMIT_ACTION} { return p::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }
|
||||
{CONFIG_DIR_REQ_BODY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
{CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
|
@ -142,7 +142,10 @@ int JSON::addArgument(const std::string& value) {
|
||||
}
|
||||
|
||||
|
||||
m_transaction->addArgument("JSON", path + data, value, 0);
|
||||
if (!m_transaction->addArgument("JSON", path + data, value, 0)) {
|
||||
// cancel parsing by returning false
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -389,6 +389,12 @@ bool Transaction::addArgument(const std::string& orig, const std::string& key,
|
||||
ms_dbg(4, "Adding request argument (" + orig + "): name \"" + \
|
||||
key + "\", value \"" + value + "\"");
|
||||
|
||||
if (m_rules->m_argumentsLimit.m_set
|
||||
&& m_variableArgs.size() >= m_rules->m_argumentsLimit.m_value) {
|
||||
ms_dbg(4, "Skipping request argument, over limit (" + std::to_string(m_rules->m_argumentsLimit.m_value) + ")")
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t k_offset = offset;
|
||||
offset = offset + key.size() + 1;
|
||||
m_variableArgs.set(key, value, offset);
|
||||
|
86
test/test-cases/regression/secargumentslimit.json
Normal file
86
test/test-cases/regression/secargumentslimit.json
Normal file
@ -0,0 +1,86 @@
|
||||
[
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing SecArgumentLimit not over limit (1/1)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
},
|
||||
"server":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":80
|
||||
},
|
||||
"request":{
|
||||
"headers":{
|
||||
"Host":"localhost",
|
||||
"User-Agent":"curl/7.38.0",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
"uri":"/?foo=bar",
|
||||
"method":"POST",
|
||||
"body": [
|
||||
"{",
|
||||
" \"k1\":\"v1\",",
|
||||
" \"k2\":\"v2\",",
|
||||
" \"k3\":\"v3\",",
|
||||
" \"k4\":\"v4\",",
|
||||
" \"k5\":\"v5\"",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"debug_log": " Running action deny",
|
||||
"http_code":403
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecArgumentsLimit 6",
|
||||
"SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"",
|
||||
"SecRule REQBODY_ERROR \"!@eq 0\" \"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}'\"",
|
||||
"SecRule ARGS:/k5/ \"@rx v5\" \"id:'1234',phase:2,deny,status:403,t:none,log,auditlog\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing SecArgumentLimit over limit (2/2)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
},
|
||||
"server":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":80
|
||||
},
|
||||
"request":{
|
||||
"headers":{
|
||||
"Host":"localhost",
|
||||
"User-Agent":"curl/7.38.0",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
"uri":"/?foo=bar",
|
||||
"method":"POST",
|
||||
"body": [
|
||||
"{",
|
||||
" \"k1\":\"v1\",",
|
||||
" \"k2\":\"v2\",",
|
||||
" \"k3\":\"v3\",",
|
||||
" \"k4\":\"v4\",",
|
||||
" \"k5\":\"v5\"",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"debug_log": "Skipping request argument, over limit",
|
||||
"http_code":400
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecArgumentsLimit 5",
|
||||
"SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"",
|
||||
"SecRule REQBODY_ERROR \"!@eq 0\" \"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}'\"",
|
||||
"SecRule ARGS:/k5/ \"@rx v5\" \"id:'1234',phase:2,deny,status:403,t:none,log,auditlog\""
|
||||
]
|
||||
}
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user