mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
MODSEC-178
This commit is contained in:
parent
a5ddb8189c
commit
1a2d377e34
@ -172,13 +172,35 @@ static void copy_rules_phase(apr_pool_t *mp,
|
||||
if (rc >= 0) copy--;
|
||||
}
|
||||
break;
|
||||
case RULE_EXCEPTION_REMOVE_TAG :
|
||||
if ((rule->actionset != NULL)&&(apr_is_empty_table(rule->actionset->actions) == 0)) {
|
||||
char *my_error_msg = NULL;
|
||||
const apr_array_header_t *tarr = NULL;
|
||||
const apr_table_entry_t *telts = NULL;
|
||||
int i;
|
||||
|
||||
tarr = apr_table_elts(rule->actionset->actions);
|
||||
telts = (const apr_table_entry_t*)tarr->elts;
|
||||
|
||||
for (i = 0; i < tarr->nelts; i++) {
|
||||
msre_action *action = (msre_action *)telts[i].val;
|
||||
if(strcmp("tag", action->metadata->name) == 0) {
|
||||
|
||||
int rc = msc_regexec(exceptions[j]->param_data,
|
||||
action->param, strlen(action->param),
|
||||
&my_error_msg);
|
||||
if (rc >= 0) copy--;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy > 0) {
|
||||
#ifdef DEBUG_CONF
|
||||
#ifdef DEBUG_CONF
|
||||
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy rule %pp [id \"%s\"]", rule, rule->actionset->id);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Copy the rule. */
|
||||
*(msre_rule **)apr_array_push(child_phase_arr) = rule;
|
||||
@ -188,9 +210,9 @@ static void copy_rules_phase(apr_pool_t *mp,
|
||||
}
|
||||
} else {
|
||||
if (mode == 2) {
|
||||
#ifdef DEBUG_CONF
|
||||
#ifdef DEBUG_CONF
|
||||
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy chain %pp for rule %pp [id \"%s\"]", rule, rule->chain_starter, rule->chain_starter->actionset->id);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Copy the rule (it belongs to the chain we want to include. */
|
||||
*(msre_rule **)apr_array_push(child_phase_arr) = rule;
|
||||
@ -1859,6 +1881,31 @@ static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_rule_remove_by_tag(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
re->type = RULE_EXCEPTION_REMOVE_TAG;
|
||||
re->param = p1;
|
||||
re->param_data = msc_pregcomp(cmd->pool, p1, 0, NULL, NULL);
|
||||
if (re->param_data == NULL) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid regular expression: %s", p1);
|
||||
}
|
||||
*(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
|
||||
|
||||
/* Remove the corresponding rules from the context straight away. */
|
||||
msre_ruleset_rule_remove_with_exception(dcfg->ruleset, re);
|
||||
|
||||
#ifdef DEBUG_CONF
|
||||
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool, "Added exception %pp (%d %s) to dcfg %pp.", re, re->type, re->param, dcfg);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
@ -2559,6 +2606,14 @@ const command_rec module_directives[] = {
|
||||
"rule ID for removal"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveByTag",
|
||||
cmd_rule_remove_by_tag,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"rule tag for removal"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveByMsg",
|
||||
cmd_rule_remove_by_msg,
|
||||
|
@ -419,6 +419,9 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) {
|
||||
msr->removed_rules = apr_array_make(msr->mp, 16, sizeof(char *));
|
||||
if (msr->removed_rules == NULL) return -1;
|
||||
|
||||
msr->removed_rules_tag = apr_array_make(msr->mp, 16, sizeof(char *));
|
||||
if (msr->removed_rules_tag == NULL) return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,7 @@ extern DSOLOCAL unsigned long int conn_read_state_limit;
|
||||
#define RULE_EXCEPTION_IMPORT_MSG 2
|
||||
#define RULE_EXCEPTION_REMOVE_ID 3
|
||||
#define RULE_EXCEPTION_REMOVE_MSG 4
|
||||
#define RULE_EXCEPTION_REMOVE_TAG 5
|
||||
|
||||
#define NBSP 160
|
||||
|
||||
@ -378,6 +379,7 @@ struct modsec_rec {
|
||||
|
||||
/* removed rules */
|
||||
apr_array_header_t *removed_rules;
|
||||
apr_array_header_t *removed_rules_tag;
|
||||
|
||||
/* When "allow" is executed the variable below is
|
||||
* updated to contain the scope of the allow action. Set
|
||||
|
77
apache2/re.c
77
apache2/re.c
@ -929,9 +929,9 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
rules = (msre_rule **)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
msre_rule *rule = rules[i];
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
apr_time_t time1 = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Reset the rule interception flag */
|
||||
msr->rule_was_intercepted = 0;
|
||||
@ -1025,14 +1025,18 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
}
|
||||
|
||||
/* Check if this rule was removed at runtime */
|
||||
if ((rule->actionset->id !=NULL) && (! apr_is_empty_array(msr->removed_rules))) {
|
||||
int j;
|
||||
if (((rule->actionset->id !=NULL) && !apr_is_empty_array(msr->removed_rules)) || (apr_is_empty_array(msr->removed_rules_tag)==0)) {
|
||||
int j, act;
|
||||
int do_process = 1;
|
||||
const char *range;
|
||||
const apr_array_header_t *tag_tarr = NULL;
|
||||
const apr_table_entry_t *tag_telts = NULL;
|
||||
|
||||
for(j = 0; j < msr->removed_rules->nelts; j++) {
|
||||
range = ((const char**)msr->removed_rules->elts)[j];
|
||||
|
||||
if(rule->actionset->id !=NULL) {
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Checking removal of rule id=\"%s\" against: %s", rule->actionset->id, range);
|
||||
}
|
||||
@ -1042,6 +1046,34 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tag_tarr = apr_table_elts(rule->actionset->actions);
|
||||
tag_telts = (const apr_table_entry_t*)tag_tarr->elts;
|
||||
|
||||
for (act = 0; act < tag_tarr->nelts; act++) {
|
||||
msre_action *action = (msre_action *)tag_telts[act].val;
|
||||
|
||||
if((action != NULL) && (action->metadata != NULL ) && strcmp("tag", action->metadata->name) == 0) {
|
||||
|
||||
for(j = 0; j < msr->removed_rules_tag->nelts; j++) {
|
||||
range = ((const char**)msr->removed_rules_tag->elts)[j];
|
||||
|
||||
|
||||
if(action->param != NULL) {
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Checking removal of rule tag=\"%s\" against: %s", (char *)action->param, range);
|
||||
}
|
||||
|
||||
if (strncasecmp(action->param, range, strlen(range)) == 0) {
|
||||
do_process = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to the next rule if this one has been removed. */
|
||||
if (do_process == 0) {
|
||||
@ -1086,15 +1118,15 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
msr_log(msr, 5, "Rule %pp: %s", rule, rule->unparsed);
|
||||
}
|
||||
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
time1 = apr_time_now();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
rc = msre_rule_process(rule, msr);
|
||||
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
rule->execution_time += (apr_time_now() - time1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Rule returned %d.", rc);
|
||||
@ -1399,6 +1431,31 @@ static int msre_ruleset_phase_rule_remove_with_exception(msre_ruleset *ruleset,
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case RULE_EXCEPTION_REMOVE_TAG :
|
||||
if ((rule->actionset != NULL)&&(apr_is_empty_table(rule->actionset->actions) == 0)) {
|
||||
char *my_error_msg = NULL;
|
||||
const apr_array_header_t *tarr = NULL;
|
||||
const apr_table_entry_t *telts = NULL;
|
||||
int act;
|
||||
|
||||
tarr = apr_table_elts(rule->actionset->actions);
|
||||
telts = (const apr_table_entry_t*)tarr->elts;
|
||||
|
||||
for (act = 0; act < tarr->nelts; act++) {
|
||||
msre_action *action = (msre_action *)telts[act].val;
|
||||
if((action != NULL) && (action->metadata != NULL) && (strcmp("tag", action->metadata->name) == 0)) {
|
||||
|
||||
int rc = msc_regexec(re->param_data,
|
||||
action->param, strlen(action->param),
|
||||
&my_error_msg);
|
||||
if (rc >= 0) {
|
||||
remove_rule = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1579,7 +1636,7 @@ char * msre_rule_generate_unparsed(apr_pool_t *pool, const msre_rule *rule, con
|
||||
case RULE_TYPE_MARKER:
|
||||
unparsed = apr_psprintf(pool, "SecMarker \"%s\"", rule->actionset->id);
|
||||
break;
|
||||
#if defined(WITH_LUA)
|
||||
#if defined(WITH_LUA)
|
||||
case RULE_TYPE_LUA:
|
||||
/* SecRuleScript */
|
||||
if (r_actions == NULL) {
|
||||
@ -1590,7 +1647,7 @@ char * msre_rule_generate_unparsed(apr_pool_t *pool, const msre_rule *rule, con
|
||||
r_args, log_escape(pool, r_actions));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return unparsed;
|
||||
|
@ -764,6 +764,10 @@ static char *msre_action_ctl_validate(msre_engine *engine, msre_action *action)
|
||||
/* ENH nothing yet */
|
||||
return NULL;
|
||||
} else
|
||||
if (strcasecmp(name, "ruleRemoveByTag") == 0) {
|
||||
/* ENH nothing yet */
|
||||
return NULL;
|
||||
} else
|
||||
if (strcasecmp(name, "requestBodyAccess") == 0) {
|
||||
if (parse_boolean(value) == -1) {
|
||||
return apr_psprintf(engine->mp, "Invalid setting for ctl name "
|
||||
@ -906,7 +910,16 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
*(const char **)apr_array_push(msr->removed_rules) = (const char *)apr_pstrdup(msr->mp, value);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Ctl: Removed rule %s.", value);
|
||||
msr_log(msr, 4, "Ctl: Removed rule by id : %s.", value);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else
|
||||
if (strcasecmp(name, "ruleRemoveByTag") == 0) {
|
||||
*(const char **)apr_array_push(msr->removed_rules_tag) = (const char *)apr_pstrdup(msr->mp, value);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Ctl: Removed rule by tag : %s.", value);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user