diff --git a/CHANGES b/CHANGES index cec15afd..7764ec22 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,8 @@ 29 Nov 2007 - 2.5.0-dev3 ------------------------ + * Added matching rules to audit log data. + * Implemented SecRequestBodyNoFilesLimit. * Enhance handling of the case where we run out of disk space while diff --git a/apache2/apache2_config.c b/apache2/apache2_config.c index a62d88f7..3c98d7c3 100644 --- a/apache2/apache2_config.c +++ b/apache2/apache2_config.c @@ -659,7 +659,7 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, const char * /* -- Configuration directives -- */ static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1) { - return add_rule(cmd, (directory_config *)_dcfg, "REQUEST_URI", "@unconditionalMatch", p1); + return add_rule(cmd, (directory_config *)_dcfg, SECACTION_TARGETS, SECACTION_ARGS, p1); } static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg, const char *p1) { diff --git a/apache2/modsecurity.c b/apache2/modsecurity.c index eec3eed0..cc543618 100644 --- a/apache2/modsecurity.c +++ b/apache2/modsecurity.c @@ -304,6 +304,9 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) { msr->tcache = apr_hash_make(msr->mp); if (msr->tcache == NULL) return -1; + msr->matched_rules = apr_array_make(msr->mp, 16, sizeof(void *)); + if (msr->matched_rules == NULL) return -1; + msr->matched_var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string)); if (msr->matched_var == NULL) return -1; diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index 4d0b42bc..6e36652b 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -114,6 +114,9 @@ extern DSOLOCAL modsec_build_type_rec modsec_build_type[]; #define RESPONSE_BODY_LIMIT_ACTION_REJECT 0 #define RESPONSE_BODY_LIMIT_ACTION_PARTIAL 1 +#define SECACTION_TARGETS "REQUEST_URI" +#define SECACTION_ARGS "@unconditionalMatch" + #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) #include "unixd.h" #define __SET_MUTEX_PERMS @@ -333,6 +336,7 @@ struct modsec_rec { apr_time_t time_checkpoint_2; apr_time_t time_checkpoint_3; + apr_array_header_t *matched_rules; msc_string *matched_var; int highest_severity; diff --git a/apache2/msc_logging.c b/apache2/msc_logging.c index 20fe4339..71e216c2 100644 --- a/apache2/msc_logging.c +++ b/apache2/msc_logging.c @@ -8,6 +8,7 @@ * write to Breach Security, Inc. at support@breach.com. * */ +#include "re.h" #include "msc_logging.h" #include "httpd.h" #include "apr_strings.h" @@ -362,6 +363,7 @@ void sec_audit_logger(modsec_rec *msr) { const apr_array_header_t *arr = NULL; apr_table_entry_t *te = NULL; char *str1 = NULL, *str2 = NULL, *text = NULL; + const msre_rule *rule = NULL; apr_size_t nbytes, nbytes_written; unsigned char md5hash[APR_MD5_DIGESTSIZE]; int was_limited = 0; @@ -732,6 +734,13 @@ void sec_audit_logger(modsec_rec *msr) { sec_auditlog_write(msr, text, strlen(text)); } + /* Matched Rules */ + for(i = 0; i < msr->matched_rules->nelts; i++) { + rule = ((msre_rule **)msr->matched_rules->elts)[i]; + text = apr_psprintf(msr->mp, "MatchedRule: %s\n", rule->unparsed); + sec_auditlog_write(msr, text, strlen(text)); + } + /* Apache error messages */ for(i = 0; i < msr->error_messages->nelts; i++) { error_message *em = (((error_message**)msr->error_messages->elts)[i]); diff --git a/apache2/re.c b/apache2/re.c index c2a98012..e84bb5d2 100644 --- a/apache2/re.c +++ b/apache2/re.c @@ -1214,6 +1214,7 @@ msre_rule *msre_rule_create(msre_ruleset *ruleset, rule->ruleset = ruleset; rule->targets = apr_array_make(ruleset->mp, 10, sizeof(const msre_var *)); rule->p1 = apr_pstrdup(ruleset->mp, targets); + rule->unparsed = apr_pstrcat(ruleset->mp, ((strcmp(SECACTION_TARGETS, targets) || strcmp(SECACTION_TARGETS, args)) ? "SecRule" : "SecAction"), " ", targets, " ", args, " ", actions, NULL); rule->filename = apr_pstrdup(ruleset->mp, fn); rule->line_num = line; @@ -1424,6 +1425,9 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr, log_escape(msr->mp, full_varname)); } + /* Save the rules that match */ + *(const msre_rule **)apr_array_push(msr->matched_rules) = rule; + /* Save the last matched var data */ msr->matched_var->name = apr_pstrdup(msr->mp, var->name); msr->matched_var->name_len = strlen(msr->matched_var->name); diff --git a/apache2/re.h b/apache2/re.h index 0be1a760..69687a6f 100644 --- a/apache2/re.h +++ b/apache2/re.h @@ -121,6 +121,7 @@ struct msre_rule { unsigned int op_negated; msre_actionset *actionset; const char *p1; + const char *unparsed; const char *filename; int line_num; int placeholder;