mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Adds support to unconditional rules
This commit is contained in:
parent
4e8bb276b8
commit
b048794f4e
@ -39,6 +39,17 @@ Driver::~Driver() {
|
||||
delete loc.back();
|
||||
}
|
||||
|
||||
int Driver::addSecAction(Rule *rule) {
|
||||
if (rule->phase >= ModSecurity::Phases::NUMBER_OF_PHASES) {
|
||||
parserError << "Unknown phase: " << std::to_string(rule->phase);
|
||||
parserError << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
rules[rule->phase].push_back(rule);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Driver::addSecRule(Rule *rule) {
|
||||
if (rule->phase >= ModSecurity::Phases::NUMBER_OF_PHASES) {
|
||||
|
@ -57,6 +57,7 @@ class Driver : public RulesProperties {
|
||||
virtual ~Driver();
|
||||
|
||||
int addSecRule(Rule *rule);
|
||||
int addSecAction(Rule *rule);
|
||||
|
||||
int result;
|
||||
|
||||
|
@ -190,6 +190,7 @@ using ModSecurity::Variables::Variable;
|
||||
%token <std::string> CONFIG_DIR_DEBUG_LOG
|
||||
%token <std::string> CONFIG_DIR_DEBUG_LVL
|
||||
|
||||
%token <std::string> CONFIG_DIR_SEC_ACTION
|
||||
%token <std::string> CONFIG_DIR_SEC_DEFAULT_ACTION
|
||||
|
||||
%token <std::string> VARIABLE
|
||||
@ -356,6 +357,24 @@ expression:
|
||||
);
|
||||
driver.addSecRule(rule);
|
||||
}
|
||||
| CONFIG_DIR_SEC_ACTION SPACE QUOTATION_MARK actions QUOTATION_MARK
|
||||
{
|
||||
Rule *rule = new Rule(
|
||||
/* op */ NULL,
|
||||
/* variables */ NULL,
|
||||
/* actions */ $4
|
||||
);
|
||||
driver.addSecAction(rule);
|
||||
}
|
||||
| CONFIG_DIR_SEC_ACTION SPACE actions
|
||||
{
|
||||
Rule *rule = new Rule(
|
||||
/* op */ NULL,
|
||||
/* variables */ NULL,
|
||||
/* actions */ $3
|
||||
);
|
||||
driver.addSecAction(rule);
|
||||
}
|
||||
| CONFIG_DIR_SEC_DEFAULT_ACTION SPACE QUOTATION_MARK actions QUOTATION_MARK
|
||||
{
|
||||
std::vector<Action *> *actions = $4;
|
||||
|
@ -39,6 +39,7 @@ DIRECTIVE (?i:SecRule)
|
||||
LOG_DATA (?i:logdata)
|
||||
|
||||
CONFIG_DIR_SEC_DEFAULT_ACTION (?i:SecDefaultAction)
|
||||
CONFIG_DIR_SEC_ACTION (?i:SecAction)
|
||||
|
||||
CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION (?i:SecPcreMatchLimitRecursion)
|
||||
CONFIG_DIR_PCRE_MATCH_LIMIT (?i:SecPcreMatchLimit)
|
||||
@ -243,6 +244,7 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
|
||||
{CONFIG_VALUE_PROCESS_PARTIAL} { return yy::seclang_parser::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); }
|
||||
{CONFIG_VALUE_REJECT} { return yy::seclang_parser::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); }
|
||||
|
||||
{CONFIG_DIR_SEC_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); }
|
||||
{CONFIG_DIR_SEC_DEFAULT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); }
|
||||
|
||||
<EXPECTING_OPERATOR>{
|
||||
|
71
src/rule.cc
71
src/rule.cc
@ -56,7 +56,7 @@ Rule::~Rule() {
|
||||
actions_runtime_pos.pop_back();
|
||||
delete a;
|
||||
}
|
||||
while (variables->empty() == false) {
|
||||
while (variables != NULL && variables->empty() == false) {
|
||||
auto *a = variables->back();
|
||||
variables->pop_back();
|
||||
delete a;
|
||||
@ -75,6 +75,7 @@ Rule::Rule(Operator *_op,
|
||||
op(_op),
|
||||
rule_id(0),
|
||||
phase(-1),
|
||||
m_unconditional(false),
|
||||
m_referenceCount(0) {
|
||||
for (Action *a : *actions) {
|
||||
if (a->action_kind == Action::ConfigurationKind) {
|
||||
@ -98,13 +99,81 @@ Rule::Rule(Operator *_op,
|
||||
phase = ModSecurity::Phases::RequestHeadersPhase;
|
||||
}
|
||||
|
||||
if (op == NULL) {
|
||||
m_unconditional = true;
|
||||
}
|
||||
|
||||
delete actions;
|
||||
}
|
||||
|
||||
|
||||
bool Rule::evaluateActions(Assay *assay) {
|
||||
int none = 0;
|
||||
int transformations = 0;
|
||||
for (Action *a : this->actions_runtime_pre) {
|
||||
None *z = dynamic_cast<None *>(a);
|
||||
if (z != NULL) {
|
||||
none++;
|
||||
}
|
||||
}
|
||||
|
||||
assay->debug(4, "Running unconditional rule.");
|
||||
|
||||
if (none == 0) {
|
||||
/*
|
||||
for (Action *a : assay->m_rules->defaultActions[this->phase]) {
|
||||
if (a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) {
|
||||
value = a->evaluate(value, assay);
|
||||
assay->debug(9, "(SecDefaultAction) T (" + \
|
||||
std::to_string(transformations) + ") " + \
|
||||
a->name + ": \"" + value +"\"");
|
||||
transformations++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
for (Action *a : this->actions_runtime_pre) {
|
||||
None *z = dynamic_cast<None *>(a);
|
||||
/*
|
||||
if (none == 0) {
|
||||
value = a->evaluate(value, assay);
|
||||
assay->debug(9, " T (" + \
|
||||
std::to_string(transformations) + ") " + \
|
||||
a->name + ": \"" + value +"\"");
|
||||
transformations++;
|
||||
}
|
||||
*/
|
||||
if (z != NULL) {
|
||||
none--;
|
||||
}
|
||||
}
|
||||
|
||||
for (Action *a : assay->m_rules->defaultActions[this->phase]) {
|
||||
if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind) {
|
||||
assay->debug(4, "(SecDefaultAction) Running action: " + a->action);
|
||||
a->evaluate(this, assay);
|
||||
}
|
||||
}
|
||||
|
||||
for (Action *a :
|
||||
this->actions_runtime_pos) {
|
||||
assay->debug(4, "Running action: " + a->action);
|
||||
a->evaluate(this, assay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Rule::evaluate(Assay *assay) {
|
||||
bool ret = false;
|
||||
std::vector<Variable *> *variables = this->variables;
|
||||
|
||||
if (m_unconditional == true) {
|
||||
return evaluateActions(assay);
|
||||
}
|
||||
|
||||
assay->debug(4, "Executing operator \"" + this->op->op \
|
||||
+ "\" with param \"" + this->op->param + "\" against " \
|
||||
+ Variable::to_s(variables) + ".");
|
||||
|
@ -37,6 +37,7 @@ class Rule {
|
||||
|
||||
~Rule();
|
||||
bool evaluate(Assay *assay);
|
||||
bool evaluateActions(Assay *assay);
|
||||
|
||||
operators::Operator *op;
|
||||
std::vector<actions::Action *> actions_conf;
|
||||
@ -64,6 +65,7 @@ class Rule {
|
||||
std::string rev;
|
||||
|
||||
private:
|
||||
bool m_unconditional;
|
||||
int m_referenceCount;
|
||||
};
|
||||
|
||||
|
63
test/test-cases/regression/secaction.json
Normal file
63
test/test-cases/regression/secaction.json
Normal file
@ -0,0 +1,63 @@
|
||||
[
|
||||
{
|
||||
"enabled": 1,
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "sec action",
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
"Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8",
|
||||
"Accept-Language": "en-us,en;q=0.5",
|
||||
"Accept-Encoding": "gzip,deflate",
|
||||
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
|
||||
"Keep-Alive": "300",
|
||||
"Connection": "keep-alive",
|
||||
"Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120",
|
||||
"Pragma": "no-cache",
|
||||
"Cache-Control": "no-cache"
|
||||
},
|
||||
"uri": "\/test.pl?param1= test ¶m2=test2",
|
||||
"protocol": "GET",
|
||||
"http_version": 1.1,
|
||||
"body": ""
|
||||
},
|
||||
"response": {
|
||||
"headers": {
|
||||
"Content-Type": "text\/xml; charset=utf-8\n\r",
|
||||
"Content-Length": "length\n\r"
|
||||
},
|
||||
"body": [
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\r",
|
||||
"<soap:Envelope xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\" xmlns:soap=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\">\n\r",
|
||||
" <soap:Body>\n\r",
|
||||
" <EnlightenResponse xmlns=\"http:\/\/clearforest.com\/\">\n\r",
|
||||
" <EnlightenResult>string<\/EnlightenResult>\n\r",
|
||||
" <\/EnlightenResponse>\n\r",
|
||||
" <\/soap:Body>\n\r",
|
||||
"<\/soap:Envelope>\n\r"
|
||||
]
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "Running unconditional rule.",
|
||||
"error_log": ""
|
||||
},
|
||||
"rules": [
|
||||
"SecRuleEngine On",
|
||||
"SecDebugLog \/tmp\/modsec_debug.log",
|
||||
"SecDebugLogLevel 9",
|
||||
"SecRule ARGS \"@contains test\" \"phase:2,id:1,t:trim\"",
|
||||
"SecAction \"phase:2,nolog,pass\""
|
||||
]
|
||||
}
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user