@@ -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 */
541541static 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