Skip to content

Commit 0c95a7a

Browse files
p0pr0ck5Felipe Zimmerle
authored andcommitted
Clean up JSON rule writer
* Escape rule actionset metadata * Escape and truncate logdata * Lazily add actionset tags as an array * Add negated rule op_param * Add unparsed rule representation
1 parent 8559399 commit 0c95a7a

File tree

1 file changed

+58
-6
lines changed

1 file changed

+58
-6
lines changed

apache2/msc_logging.c

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -539,26 +539,49 @@ static void format_performance_variables_json(modsec_rec *msr, yajl_gen g) {
539539
* Write detailed information about a rule and its actionset into a JSON generator
540540
*/
541541
static void write_rule_json(modsec_rec *msr, const msre_rule *rule, yajl_gen g) {
542-
int present = 0;
542+
const apr_array_header_t *tarr;
543+
const apr_table_entry_t *telts;
544+
int been_opened = 0;
545+
int k;
543546

544547
yajl_gen_map_open(g);
545548

546549
yajl_string(g, "actionset");
547550
yajl_gen_map_open(g);
548551
if (rule->actionset->id) {
549-
yajl_kv_string(g, "id", rule->actionset->id);
552+
yajl_kv_string(g, "id", log_escape(msr->mp, rule->actionset->id));
550553
}
551554
if (rule->actionset->rev) {
552-
yajl_kv_string(g, "rev", rule->actionset->rev);
555+
yajl_kv_string(g, "rev", log_escape(msr->mp, rule->actionset->rev));
553556
}
554557
if (rule->actionset->msg) {
555-
yajl_kv_string(g, "msg", rule->actionset->msg);
558+
msc_string *var = (msc_string *)apr_palloc(msr->mp, sizeof(msc_string));
559+
var->value = (char *)rule->actionset->msg;
560+
var->value_len = strlen(rule->actionset->msg);
561+
expand_macros(msr, var, NULL, msr->mp);
562+
563+
yajl_kv_string(g, "msg", log_escape_ex(msr->mp, var->value, var->value_len));
556564
}
557565
if (rule->actionset->version) {
558-
yajl_kv_string(g, "version", rule->actionset->version);
566+
yajl_kv_string(g, "version", log_escape(msr->mp, rule->actionset->version));
559567
}
560568
if (rule->actionset->logdata) {
561-
yajl_kv_string(g, "logdata", rule->actionset->logdata);
569+
msc_string *var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
570+
var->value = (char *)rule->actionset->logdata;
571+
var->value_len = strlen(rule->actionset->logdata);
572+
expand_macros(msr, var, NULL, msr->mp);
573+
574+
char *logdata = apr_pstrdup(msr->mp, log_escape_hex(msr->mp, (unsigned char *)var->value, var->value_len));
575+
576+
// if it is > 512 bytes, then truncate at 512 with ellipsis.
577+
if (strlen(logdata) > 515) {
578+
logdata[512] = '.';
579+
logdata[513] = '.';
580+
logdata[514] = '.';
581+
logdata[515] = '\0';
582+
}
583+
584+
yajl_kv_string(g, "logdata", logdata);
562585
}
563586
if (rule->actionset->severity != NOT_SET) {
564587
yajl_kv_int(g, "severity", rule->actionset->severity);
@@ -576,13 +599,41 @@ static void write_rule_json(modsec_rec *msr, const msre_rule *rule, yajl_gen g)
576599
if (rule->actionset->is_chained && (rule->chain_starter == NULL)) {
577600
yajl_kv_bool(g, "chain_starter", 1);
578601
}
602+
603+
// tags, lazily opened
604+
tarr = apr_table_elts(rule->actionset->actions);
605+
telts = (const apr_table_entry_t*)tarr->elts;
606+
for (k = 0; k < tarr->nelts; k++) {
607+
msre_action *action = (msre_action *)telts[k].val;
608+
if (strcmp(telts[k].key, "tag") == 0) {
609+
if (been_opened == 0) {
610+
yajl_string(g, "tags");
611+
yajl_gen_array_open(g);
612+
been_opened = 1;
613+
}
614+
615+
// expand variables in the tag
616+
msc_string *var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
617+
var->value = (char *)action->param;
618+
var->value_len = strlen(action->param);
619+
expand_macros(msr, var, NULL, msr->mp);
620+
621+
yajl_string(g, log_escape(msr->mp, var->value));
622+
}
623+
}
624+
625+
if (been_opened == 1) {
626+
yajl_gen_array_close(g);
627+
}
628+
579629
yajl_gen_map_close(g);
580630

581631
yajl_string(g, "operator");
582632
yajl_gen_map_open(g);
583633
yajl_kv_string(g, "operator", rule->op_name);
584634
yajl_kv_string(g, "operator_param", rule->op_param);
585635
yajl_kv_string(g, "target", rule->p1);
636+
yajl_kv_bool(g, "negated", rule->op_negated);
586637
yajl_gen_map_close(g);
587638

588639
yajl_string(g, "config");
@@ -591,6 +642,7 @@ static void write_rule_json(modsec_rec *msr, const msre_rule *rule, yajl_gen g)
591642
yajl_kv_int(g, "line_num", rule->line_num);
592643
yajl_gen_map_close(g);
593644

645+
yajl_kv_string(g, "unparsed", rule->unparsed);
594646
yajl_kv_bool(g, "is_matched", chained_is_matched(msr, rule));
595647

596648
yajl_gen_map_close(g);

0 commit comments

Comments
 (0)