Remove ctl:ruleUpdateTarget* and add ctl:ruleRemovetarget*

This commit is contained in:
brenosilva 2012-08-02 18:04:53 +00:00
parent 543a7db8a7
commit 592ec392d1
8 changed files with 189 additions and 48 deletions

View File

@ -376,6 +376,10 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) {
msr->pattern_to_sanitize = apr_table_make(msr->mp, 32);
if (msr->pattern_to_sanitize == NULL) return -1;
/* remove targets */
msr->removed_targets = apr_table_make(msr->mp, 16);
if (msr->removed_targets == NULL) return -1;
/* Initialise cookies */
msr->request_cookies = apr_table_make(msr->mp, 16);
if (msr->request_cookies == NULL) return -1;

View File

@ -416,6 +416,9 @@ struct modsec_rec {
apr_array_header_t *removed_rules_tag;
apr_array_header_t *removed_rules_msg;
/* removed targets */
apr_table_t *removed_targets;
/* When "allow" is executed the variable below is
* updated to contain the scope of the allow action. Set
* at 0 by default, it will have ACTION_ALLOW if we are

View File

@ -13,6 +13,7 @@
*/
#include "msc_crypt.h"
#include "msc_util.h"
#include "apr_sha1.h"
#include "apr_uri.h"
#include "acmp.h"
@ -287,7 +288,7 @@ int init_response_body_html_parser(modsec_rec *msr) {
}
if((msr->r->content_encoding == NULL)||(apr_strnatcasecmp(msr->r->content_encoding,"(null)")==0)){
charset=strcasestr(msr->r->content_type,"charset=");
charset=ap_strcasestr(msr->r->content_type,"charset=");
if(charset == NULL){
if (msr->txcfg->debuglog_level >= 4)
msr_log(msr, 4, "init_response_body_html_parser: assuming ISO-8859-1.");
@ -1013,7 +1014,7 @@ int inject_encrypted_response_body(modsec_rec *msr, int elts) {
encoding = (const char *) htmlGetMetaEncoding(msr->crypto_html_tree);
if (ctype && encoding == NULL) {
if (ctype && (p = strcasestr(ctype, "charset=") , p != NULL)) {
if (ctype && (p = ap_strcasestr(ctype, "charset=") , p != NULL)) {
p += 8 ;
if (encoding = apr_pstrndup(msr->mp, p, strcspn(p, " ;") ), encoding) {
xmlCharEncoding enc;

View File

@ -569,8 +569,8 @@ char *file_basename(apr_pool_t *mp, const char *filename) {
return d;
}
#if defined(WIN32) || !defined(HAVE_STRCASESTR)
/*
#if (defined(WIN32) || (HAVE_STRCASESTR == 0))
char *strcasestr(const char *haystack, const char *needle) {
char aux, lower_aux;
int length;
@ -589,6 +589,7 @@ char *strcasestr(const char *haystack, const char *needle) {
return ((char *)haystack);
}
#endif
*/
#ifdef WIN32
int inet_pton(int family, const char *src, void *dst) {
struct addrinfo addr;

View File

@ -32,9 +32,11 @@
#include <ws2tcpip.h>
int DSOLOCAL inet_pton(int family, const char *src, void *dst);
#endif
#if defined(WIN32) || !defined(HAVE_STRCASESTR)
/*
#if (defined(WIN32) || (HAVE_STRCASESTR == 0))
char DSOLOCAL *strcasestr(const char *haystack, const char *needle);
#endif
*/
int DSOLOCAL normalize_path_inplace(unsigned char *input, int len, int win, int *changed);

View File

@ -32,6 +32,7 @@ static const char *const severities[] = {
NULL,
};
static int fetch_target_exception(msre_rule *rule, modsec_rec *msr, msre_var *var, const char *exceptions);
static apr_status_t msre_parse_targets(msre_ruleset *ruleset, const char *text,
apr_array_header_t *arr, char **error_msg);
static char *msre_generate_target_string(apr_pool_t *pool, msre_rule *rule);
@ -42,6 +43,110 @@ static msre_action *msre_create_action(msre_engine *engine, const char *name,
static apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr);
/* -- Actions, variables, functions and operator functions ----------------- */
/**
* \brief Remove rule targets to be processed
*
* \param rule Pointer to the rule
* \param msr ModSecurity transaction resource
* \param var Pointer to target structure.
* \param targets Exception list.
*/
static int fetch_target_exception(msre_rule *rule, modsec_rec *msr, msre_var *var, const char *exceptions) {
const char *targets = NULL;
char *savedptr = NULL, *target = NULL;
char *c = NULL, *name = NULL, *value = NULL;
char *variable = NULL, *myvar = NULL;
char *myvalue = NULL, *myname = NULL;
int match;
if(msr == NULL)
return 0;
if(var == NULL)
return 0;
if(rule == NULL)
return 0;
if(rule->actionset == NULL)
return 0;
if(rule->actionset->id !=NULL) {
myvar = apr_pstrdup(msr->mp, var->name);
c = strchr(myvar,':');
if(c != NULL) {
myname = apr_strtok(myvar,":",&myvalue);
} else {
myname = myvar;
}
match = 0;
targets = apr_pstrdup(msr->mp, exceptions);
if(targets != NULL) {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "fetch_target_exception: Found exception target list [%s] for rule id %s", targets, rule->actionset->id);
}
target = apr_strtok((char *)targets, ",", &savedptr);
while(target != NULL) {
variable = apr_pstrdup(msr->mp, target);
c = strchr(variable,':');
if(c != NULL) {
name = apr_strtok(variable,":",&value);
} else {
name = variable;
}
if((strlen(myname) == strlen(name)) &&
(strncasecmp(myname, name,strlen(myname)) == 0)) {
if(value != NULL && myvalue != NULL) {
if((strlen(myvalue) == strlen(value)) &&
strncasecmp(myvalue,value,strlen(myvalue)) == 0) {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "fetch_target_exception: Target %s will not be processed.", target);
}
match = 1;
}
} else if (value == NULL && myvalue == NULL) {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "fetch_target_exception: Target %s will not be processed.", target);
}
match = 1;
} else if (value == NULL && myvalue != NULL) {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "fetch_target_exception: Target %s will not be processed.", target);
}
match = 1;
}
}
target = apr_strtok(NULL, ",", &savedptr);
}
} else {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "fetch_target_exception: No exception target found for rule id %s.", rule->actionset->id);
}
}
}
if(match)
return 1;
return 0;
}
/**
* \brief Update target for all matching rules in set, in any phase
*
@ -2406,7 +2511,11 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
apr_time_t time_before_op = 0;
char *my_error_msg = NULL;
const char *full_varname = NULL;
int rc;
const apr_array_header_t *tarr = NULL;
const apr_table_entry_t *telts = NULL;
rule_exception *re = NULL;
char *exceptions = NULL;
int rc, i;
/* determine the full var name if not already resolved
*
@ -2427,6 +2536,33 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
full_varname = var->name;
}
tarr = apr_table_elts(msr->removed_targets);
telts = (const apr_table_entry_t*)tarr->elts;
for (i = 0; i < tarr->nelts; i++) {
exceptions = (char *)telts[i].key;
re = (rule_exception *)telts[i].val;
rc = msre_ruleset_rule_matches_exception(rule, re);
if (rc > 0) {
rc = fetch_target_exception(rule, msr, var, exceptions);
if(rc > 0) {
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Executing operator \"%s%s\" with param \"%s\" against %s skipped.",
(rule->op_negated ? "!" : ""), rule->op_name,
log_escape(msr->mp, rule->op_param), full_varname);
}
return RULE_NO_MATCH;
}
}
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Executing operator \"%s%s\" with param \"%s\" against %s.",
(rule->op_negated ? "!" : ""), rule->op_name,
@ -2438,17 +2574,17 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
var->value_len));
}
#if defined(PERFORMANCE_MEASUREMENT)
#if defined(PERFORMANCE_MEASUREMENT)
time_before_op = apr_time_now();
#else
#else
if (msr->txcfg->debuglog_level >= 4 || msr->txcfg->max_rule_time > 0) {
time_before_op = apr_time_now();
}
#endif
#endif
rc = rule->op_metadata->execute(msr, rule, var, &my_error_msg);
#if defined(PERFORMANCE_MEASUREMENT)
#if defined(PERFORMANCE_MEASUREMENT)
{
/* Record performance but do not log anything. */
apr_time_t t1 = apr_time_now();

View File

@ -885,36 +885,36 @@ static char *msre_action_ctl_validate(msre_engine *engine, msre_action *action)
return NULL;
} else
if (strcasecmp(name, "ruleUpdateTargetById") == 0) {
if (strcasecmp(name, "ruleRemoveTargetById") == 0) {
char *parm = NULL;
char *savedptr = NULL;
parm = apr_strtok(value,";",&savedptr);
if(parm == NULL && savedptr == NULL)
return apr_psprintf(engine->mp, "ruleUpdateTargetById must has at least id;append_value");
return apr_psprintf(engine->mp, "ruleRemoveTargetById must has at least id;append_value");
return NULL;
} else
if (strcasecmp(name,"ruleUpdateTargetByTag") == 0) {
if (strcasecmp(name,"ruleRemoveTargetByTag") == 0) {
char *parm = NULL;
char *savedptr = NULL;
parm = apr_strtok(value,";",&savedptr);
if(parm == NULL && savedptr == NULL)
return apr_psprintf(engine->mp, "ruleUpdateTargetByTag must has at least tag;append_value");
return apr_psprintf(engine->mp, "ruleRemoveTargetByTag must has at least tag;append_value");
if (!msc_pregcomp(engine->mp, parm, 0, NULL, NULL)) {
return apr_psprintf(engine->mp, "ModSecurity: Invalid regular expression \"%s\"", parm);
}
return NULL;
} else
if (strcasecmp(name,"ruleUpdateTargetByMsg") == 0) {
if (strcasecmp(name,"ruleRemoveTargetByMsg") == 0) {
char *parm = NULL;
char *savedptr = NULL;
parm = apr_strtok(value,";",&savedptr);
if(parm == NULL && savedptr == NULL)
return apr_psprintf(engine->mp, "ruleUpdateTargetByMsg must has at least msg;append_value");
return apr_psprintf(engine->mp, "ruleRemoveTargetByMsg must has at least msg;append_value");
if (!msc_pregcomp(engine->mp, parm, 0, NULL, NULL)) {
return apr_psprintf(engine->mp, "ModSecurity: Invalid regular expression \"%s\"", parm);
}
@ -1017,7 +1017,7 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
if (strcasecmp(name, "ruleRemoveByTag") == 0) {
rule_exception *re = apr_pcalloc(mptmp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_TAG;
re->param = (const char *)apr_pstrdup(msr->mp, value);;
re->param = (const char *)apr_pstrdup(msr->mp, value);
re->param_data = msc_pregcomp(msr->mp, re->param, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", re->param);
@ -1035,7 +1035,7 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
if (strcasecmp(name, "ruleRemoveByMsg") == 0) {
rule_exception *re = apr_pcalloc(mptmp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_MSG;
re->param = (const char *)apr_pstrdup(msr->mp, value);;
re->param = (const char *)apr_pstrdup(msr->mp, value);
re->param_data = msc_pregcomp(msr->mp, re->param, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", re->param);
@ -1199,76 +1199,70 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
return 1;
} else
if (strcasecmp(name, "ruleUpdateTargetById") == 0) {
if (strcasecmp(name, "ruleRemoveTargetById") == 0) {
rule_exception *re = NULL;
char *p1 = NULL, *p2 = NULL, *p3 = NULL;
char *p1 = NULL, *p2 = NULL;
char *savedptr = NULL;
p1 = apr_strtok(value,";",&savedptr);
p2 = apr_strtok(NULL,";",&savedptr);
p3 = apr_strtok(NULL,";",&savedptr);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: ruleUpdateTargetById id=%s append=%s replace=%s", p1, p2, p3);
msr_log(msr, 4, "Ctl: ruleUpdateTargetById id=%s targets=%s", p1, p2);
}
re = apr_pcalloc(mptmp, sizeof(rule_exception));
re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_ID;
re->param = p1;
msre_ruleset_rule_update_target_matching_exception(msr, rule->ruleset, re, p2, p3);
re->param = (const char *)apr_pstrdup(msr->mp, p1);
apr_table_addn(msr->removed_targets, apr_pstrdup(msr->mp, p2), (void *)re);
return 1;
} else
if (strcasecmp(name, "ruleUpdateTargetByTag") == 0) {
if (strcasecmp(name, "ruleRemoveTargetByTag") == 0) {
rule_exception *re = NULL;
char *p1 = NULL, *p2 = NULL, *p3 = NULL;
char *p1 = NULL, *p2 = NULL;
char *savedptr = NULL;
p1 = apr_strtok(value,";",&savedptr);
p2 = apr_strtok(NULL,";",&savedptr);
p3 = apr_strtok(NULL,";",&savedptr);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: ruleUpdateTargetByTag tag=%s append=%s replace=%s", p1, p2, p3);
msr_log(msr, 4, "Ctl: ruleRemoveTargetByTag tag=%s targets=%s", p1, p2);
}
re = apr_pcalloc(mptmp, sizeof(rule_exception));
re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_TAG;
re->param = p1;
re->param_data = msc_pregcomp(mptmp, p1, 0, NULL, NULL);
re->param = (const char *)apr_pstrdup(msr->mp, p1);
re->param_data = msc_pregcomp(msr->mp, p1, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", p1);
return -1;
}
msre_ruleset_rule_update_target_matching_exception(msr, rule->ruleset, re, p2, p3);
apr_table_addn(msr->removed_targets, apr_pstrdup(msr->mp, p2), (void *)re);
return 1;
} else
if (strcasecmp(name, "ruleUpdateTargetByMsg") == 0) {
if (strcasecmp(name, "ruleRemoveTargetByMsg") == 0) {
rule_exception *re = NULL;
char *p1 = NULL, *p2 = NULL, *p3 = NULL;
char *p1 = NULL, *p2 = NULL;
char *savedptr = NULL;
p1 = apr_strtok(value,";",&savedptr);
p2 = apr_strtok(NULL,";",&savedptr);
p3 = apr_strtok(NULL,";",&savedptr);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: ruleUpdateTargetByMsg tag=%s append=%s replace=%s", p1, p2, p3);
msr_log(msr, 4, "Ctl: ruleUpdateTargetByMsg msg=%s targets=%s", p1, p2);
}
re = apr_pcalloc(mptmp, sizeof(rule_exception));
re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_MSG;
re->param = p1;
re->param_data = msc_pregcomp(mptmp, p1, 0, NULL, NULL);
re->param = apr_pstrdup(msr->mp, p1);
re->param_data = msc_pregcomp(msr->mp, p1, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", p1);
return -1;
}
msre_ruleset_rule_update_target_matching_exception(msr, rule->ruleset, re, p2, p3);
apr_table_addn(msr->removed_targets, apr_pstrdup(msr->mp, p2), (void *)re);
return 1;
}
else {