MODSEC-178

This commit is contained in:
brenosilva 2011-03-28 18:47:58 +00:00
parent a5ddb8189c
commit 1a2d377e34
5 changed files with 220 additions and 90 deletions

View File

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

View File

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

View File

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

View File

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

View File

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