mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Basic implementation of skipAfter (still need to implement placeholders so it works with removed rules). See #258.
This commit is contained in:
parent
974298a76c
commit
9d49adf028
4
CHANGES
4
CHANGES
@ -2,6 +2,10 @@
|
|||||||
17 Oct 2007 - 2.5.0-dev3
|
17 Oct 2007 - 2.5.0-dev3
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
* Added skipAfter:<id> action to allow skipping all rules until a rule
|
||||||
|
with a specified ID is reached. Rule execution then continues after
|
||||||
|
the specified rule.
|
||||||
|
|
||||||
* Added ctl:ruleRemoveById action to allow rule removal on a match.
|
* Added ctl:ruleRemoveById action to allow rule removal on a match.
|
||||||
|
|
||||||
* Added a @containsWord operator that will match a given string anywhere in
|
* Added a @containsWord operator that will match a given string anywhere in
|
||||||
|
39
apache2/re.c
39
apache2/re.c
@ -425,6 +425,7 @@ msre_actionset *msre_actionset_create(msre_engine *engine, const char *text,
|
|||||||
/* Flow */
|
/* Flow */
|
||||||
actionset->is_chained = NOT_SET;
|
actionset->is_chained = NOT_SET;
|
||||||
actionset->skip_count = NOT_SET;
|
actionset->skip_count = NOT_SET;
|
||||||
|
actionset->skip_after = NOT_SET_P;
|
||||||
|
|
||||||
/* Disruptive */
|
/* Disruptive */
|
||||||
actionset->intercept_action = NOT_SET;
|
actionset->intercept_action = NOT_SET;
|
||||||
@ -501,6 +502,7 @@ msre_actionset *msre_actionset_merge(msre_engine *engine, msre_actionset *parent
|
|||||||
/* Flow */
|
/* Flow */
|
||||||
merged->is_chained = child->is_chained;
|
merged->is_chained = child->is_chained;
|
||||||
if (child->skip_count != NOT_SET) merged->skip_count = child->skip_count;
|
if (child->skip_count != NOT_SET) merged->skip_count = child->skip_count;
|
||||||
|
if (child->skip_after != NOT_SET_P) merged->skip_after = child->skip_after;
|
||||||
|
|
||||||
/* Disruptive */
|
/* Disruptive */
|
||||||
if (child->intercept_action != NOT_SET) {
|
if (child->intercept_action != NOT_SET) {
|
||||||
@ -558,6 +560,7 @@ static void msre_actionset_set_defaults(msre_actionset *actionset) {
|
|||||||
/* Flow */
|
/* Flow */
|
||||||
if (actionset->is_chained == NOT_SET) actionset->is_chained = 0;
|
if (actionset->is_chained == NOT_SET) actionset->is_chained = 0;
|
||||||
if (actionset->skip_count == NOT_SET) actionset->skip_count = 0;
|
if (actionset->skip_count == NOT_SET) actionset->skip_count = 0;
|
||||||
|
if (actionset->skip_after == NOT_SET_P) actionset->skip_after = NULL;
|
||||||
|
|
||||||
/* Disruptive */
|
/* Disruptive */
|
||||||
if (actionset->intercept_action == NOT_SET) actionset->intercept_action = ACTION_NONE;
|
if (actionset->intercept_action == NOT_SET) actionset->intercept_action = ACTION_NONE;
|
||||||
@ -629,6 +632,7 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
|||||||
apr_array_header_t *arr = NULL;
|
apr_array_header_t *arr = NULL;
|
||||||
msre_rule **rules;
|
msre_rule **rules;
|
||||||
apr_status_t rc;
|
apr_status_t rc;
|
||||||
|
const char *skip_after = NULL;
|
||||||
int i, mode, skip;
|
int i, mode, skip;
|
||||||
|
|
||||||
/* First determine which set of rules we need to use. */
|
/* First determine which set of rules we need to use. */
|
||||||
@ -667,6 +671,30 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
|||||||
apr_time_t time1 = 0;
|
apr_time_t time1 = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: Still need to skip over placeholders
|
||||||
|
|
||||||
|
/* SKIP_RULES is used to skip all rules until we hit a placeholder
|
||||||
|
* with the specified rule ID and then resume execution after that.
|
||||||
|
*/
|
||||||
|
if (mode == SKIP_RULES) {
|
||||||
|
/* Go to the next rule if we have not yet hit the skip_after ID */
|
||||||
|
// TODO: must be a placeholder as well
|
||||||
|
if ((rule->actionset->id == NULL) || (strcmp(skip_after, rule->actionset->id) != 0)) {
|
||||||
|
if (msr->txcfg->debuglog_level >= 9) {
|
||||||
|
msr_log(msr, 9, "Skipping rule id=\"%s\" while looking for id=\"%s\"", (rule->actionset->id ? rule->actionset->id : "(none)"), skip_after);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (msr->txcfg->debuglog_level >= 4) {
|
||||||
|
msr_log(msr, 4, "Continuing execution after rule id=\"%s\"", skip_after);
|
||||||
|
}
|
||||||
|
skip_after = NULL;
|
||||||
|
mode = NEXT_RULE;
|
||||||
|
|
||||||
|
/* Go to the rule *after* this one to continue execution. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* NEXT_CHAIN is used when one of the rules in a chain
|
/* NEXT_CHAIN is used when one of the rules in a chain
|
||||||
* fails to match and then we need to skip the remaining
|
* fails to match and then we need to skip the remaining
|
||||||
* rules in that chain in order to get to the next
|
* rules in that chain in order to get to the next
|
||||||
@ -796,6 +824,17 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rule->actionset->skip_after != NULL) {
|
||||||
|
skip_after = rule->actionset->skip_after;
|
||||||
|
mode = SKIP_RULES;
|
||||||
|
|
||||||
|
if (msr->txcfg->debuglog_level >= 9) {
|
||||||
|
msr_log(msr, 9, "Skipping after rule id=\"%s\" -> mode SKIP_RULES.", skip_after);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* We had a match but the transaction was not
|
/* We had a match but the transaction was not
|
||||||
* intercepted. In that case we proceed with the
|
* intercepted. In that case we proceed with the
|
||||||
* next rule...
|
* next rule...
|
||||||
|
@ -235,6 +235,7 @@ struct msre_actionset {
|
|||||||
/* Flow */
|
/* Flow */
|
||||||
int is_chained;
|
int is_chained;
|
||||||
int skip_count;
|
int skip_count;
|
||||||
|
const char *skip_after;
|
||||||
|
|
||||||
/* Disruptive */
|
/* Disruptive */
|
||||||
int intercept_action;
|
int intercept_action;
|
||||||
|
@ -420,6 +420,21 @@ static apr_status_t msre_action_skip_init(msre_engine *engine, msre_actionset *a
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* skipAfter */
|
||||||
|
|
||||||
|
static char *msre_action_skipAfter_validate(msre_engine *engine, msre_action *action) {
|
||||||
|
/* ENH Add validation. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static apr_status_t msre_action_skipAfter_init(msre_engine *engine, msre_actionset *actionset,
|
||||||
|
msre_action *action)
|
||||||
|
{
|
||||||
|
// TODO: Need to keep track of skipAfter IDs so we can insert placeholders after we get to the real rule with that ID.
|
||||||
|
actionset->skip_after = action->param;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* allow */
|
/* allow */
|
||||||
|
|
||||||
static apr_status_t msre_action_allow_init(msre_engine *engine, msre_actionset *actionset,
|
static apr_status_t msre_action_allow_init(msre_engine *engine, msre_actionset *actionset,
|
||||||
@ -1660,6 +1675,18 @@ void msre_engine_register_default_actions(msre_engine *engine) {
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* skipAfter */
|
||||||
|
msre_engine_action_register(engine,
|
||||||
|
"skipAfter",
|
||||||
|
ACTION_DISRUPTIVE,
|
||||||
|
1, 1,
|
||||||
|
NO_PLUS_MINUS,
|
||||||
|
ACTION_CARDINALITY_ONE,
|
||||||
|
msre_action_skipAfter_validate,
|
||||||
|
msre_action_skipAfter_init,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
/* allow */
|
/* allow */
|
||||||
msre_engine_action_register(engine,
|
msre_engine_action_register(engine,
|
||||||
"allow",
|
"allow",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user