mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-16 07:56:12 +03:00
Remove ctl:ruleUpdateTarget* and add ctl:ruleRemovetarget*
This commit is contained in:
parent
543a7db8a7
commit
592ec392d1
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -624,7 +624,7 @@ static int multipart_process_boundary(modsec_rec *msr, int last_part, char **err
|
||||
&&(msr->mpd->mpp->tmp_file_fd != 0))
|
||||
{
|
||||
close(msr->mpd->mpp->tmp_file_fd);
|
||||
msr->mpd->mpp->tmp_file_fd = -1;
|
||||
msr->mpd->mpp->tmp_file_fd = -1;
|
||||
}
|
||||
|
||||
if (msr->mpd->mpp->type != MULTIPART_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;
|
||||
|
@ -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);
|
||||
|
||||
|
152
apache2/re.c
152
apache2/re.c
@ -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,28 +2536,55 @@ 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,
|
||||
log_escape(msr->mp, rule->op_param), full_varname);
|
||||
(rule->op_negated ? "!" : ""), rule->op_name,
|
||||
log_escape(msr->mp, rule->op_param), full_varname);
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Target value: \"%s\"", log_escape_nq_ex(msr->mp, var->value,
|
||||
var->value_len));
|
||||
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();
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user