Delays variable name resolution to whenever it is necessary

This commit is contained in:
Felipe Zimmerle 2020-08-25 09:14:40 -03:00 committed by Felipe Zimmerle
parent 64bffdebc4
commit 9f0e345f43
5 changed files with 55 additions and 12 deletions

View File

@ -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) +

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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}'\""
]
}
]