diff --git a/src/operators/operator.cc b/src/operators/operator.cc index 6161bcdb..a9c984ee 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -83,10 +83,12 @@ bool Operator::evaluateInternal(Transaction *transaction, std::string Operator::resolveMatchMessage(Transaction *t, - std::string key, std::string value) { + const VariableValue *v) { std::string ret = m_match_message; if (ret.empty() == true) { + const std::string &key = v->getKeyWithCollection(); + const std::string &value = v->getValue(); if (m_couldContainsMacro == false) { ret = "Matched \"Operator `" + m_op + "' with parameter `" + utils::string::limitTo(200, m_param) + diff --git a/src/operators/operator.h b/src/operators/operator.h index 97ca5775..a45e2c26 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -128,7 +128,7 @@ class Operator { } virtual std::string resolveMatchMessage(Transaction *t, - std::string key, std::string value); + const VariableValue *v); std::string m_match_message; diff --git a/src/rule_with_operator.cc b/src/rule_with_operator.cc index 1e7bf864..15845651 100644 --- a/src/rule_with_operator.cc +++ b/src/rule_with_operator.cc @@ -79,8 +79,9 @@ RuleWithOperator::~RuleWithOperator() { void RuleWithOperator::updateMatchedVars(Transaction *trans, - const std::string &key, + const VariableValue *v, const bpstd::string_view &value) { + const std::string &key = v->getKeyWithCollection(); ms_dbg_a(trans, 9, "Matched vars updated."); trans->m_variableMatchedVar.set(value, trans->m_variableOffset); trans->m_variableMatchedVarName.set(key, trans->m_variableOffset); @@ -100,7 +101,7 @@ inline void RuleWithOperator::cleanMatchedVars(Transaction *trans) { bool RuleWithOperator::executeOperatorAt(Transaction *trans, - const std::string &key, + const VariableValue *v, const bpstd::string_view &value) const { #if MSC_EXEC_CLOCK_ENABLED clock_t begin = clock(); @@ -112,7 +113,7 @@ bool RuleWithOperator::executeOperatorAt(Transaction *trans, ms_dbg_a(trans, 9, "Target value: \"" \ + utils::string::limitTo(80, utils::string::toHexIfNeeded(value.to_string())) \ - + "\" (Variable: " + key + ")"); + + "\" (Variable: " + v->getKeyWithCollection() + ")"); ret = m_operator->evaluateInternal(trans, this, value, trans->messageGetLast()); @@ -276,7 +277,6 @@ bool RuleWithOperator::evaluate(Transaction *trans) const { TransformationsResults transformationsResults; const VariableValue *v = vv.get(); const std::string &value = v->getValue(); - const std::string &key = v->getKeyWithCollection(); if (exclusion.contains(v) || std::find_if(trans->m_ruleRemoveTargetById.begin(), @@ -287,6 +287,7 @@ bool RuleWithOperator::evaluate(Transaction *trans) const { ) { continue; } + if (exclusion.contains(v) || std::find_if(trans->m_ruleRemoveTargetByTag.begin(), trans->m_ruleRemoveTargetByTag.end(), @@ -309,11 +310,10 @@ bool RuleWithOperator::evaluate(Transaction *trans) const { auto &valueTemp = *iter; bpstd::string_view view = *valueTemp.getAfter(); - ret = executeOperatorAt(trans, key, view); + ret = executeOperatorAt(trans, v, view); if (ret == true) { - trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans, - key, value); + trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans, v); for (const auto &i : v->getOrigin()) { trans->messageGetLast()->m_reference.append(i.toText()); @@ -334,7 +334,7 @@ bool RuleWithOperator::evaluate(Transaction *trans) const { iter2++; } - updateMatchedVars(trans, key, view); + updateMatchedVars(trans, v, view); executeActionsIndependentOfChainedRuleResult(trans); globalRet = true; diff --git a/src/rule_with_operator.h b/src/rule_with_operator.h index 15df1ba5..29cfd4ce 100644 --- a/src/rule_with_operator.h +++ b/src/rule_with_operator.h @@ -78,11 +78,11 @@ class RuleWithOperator : public RuleWithActions { variables::Variables *eclusion, Transaction *trans) const; bool executeOperatorAt(Transaction *transaction, - const std::string &key, + const VariableValue *v, const bpstd::string_view &value) const; static void updateMatchedVars(Transaction *transaction, - const std::string &key, + const VariableValue *v, const bpstd::string_view &value); static void cleanMatchedVars(Transaction *trasn); diff --git a/test/test-cases/regression/rule-920274.json b/test/test-cases/regression/rule-920274.json index 4eb0fd6f..e9349bd1 100644 --- a/test/test-cases/regression/rule-920274.json +++ b/test/test-cases/regression/rule-920274.json @@ -38,6 +38,47 @@ "SecDefaultAction \"phase:2,deny,block,status:400,log\"", "SecRule REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:Cookie \"@validateByteRange 32,34,38,42-59,61,65-90,95,97-122\" \"id:920274,phase:2,block,t:none,t:urlDecodeUni,msg:'Invalid character in request headers (outside of very strict set)',logdata:'%{MATCHED_VAR_NAME}=%{MATCHED_VAR}',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-protocol',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',tag:'paranoia-level/4',ver:'OWASP_CRS/3.1.0',severity:'CRITICAL',setvar:'tx.msg=%{rule.msg}',setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}',setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'\"" ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Byte ranges :: OWASP CRS id:920274 - II", + "client":{ + "ip":"200.249.12.31", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent": "ThisIsATest%60 II", + "User-Agent2": "ThisIsATest%60 II" + }, + "uri":"/", + "method":"GET" + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "http_code":400, + "debug_log":"Invalid character in request headers" + }, + "rules":[ + "SecRuleEngine On", + "SecDefaultAction \"phase:2,deny,block,status:400,log\"", + "SecRule REQUEST_HEADERS|!REQUEST_HEADERS:'/User-Agent.*2/'|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:Cookie \"@validateByteRange 32,34,38,42-59,61,65-90,95,97-122\" \"id:920274,phase:2,block,t:none,t:urlDecodeUni,msg:'Invalid character in request headers (outside of very strict set)',logdata:'%{MATCHED_VAR_NAME}=%{MATCHED_VAR}',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-protocol',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',tag:'paranoia-level/4',ver:'OWASP_CRS/3.1.0',severity:'CRITICAL',setvar:'tx.msg=%{rule.msg}',setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}',setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'\"" + ] } ]