diff --git a/CHANGES b/CHANGES index d0480e2c..0bd0210a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ 05 Mar 2009 - 2.5.9-dev1 ------------------------ + * Added macro expansion for append/prepend action. + * Fixed race condition in concurrent updates of persistent counters. Updates are now atomic. diff --git a/apache2/re_actions.c b/apache2/re_actions.c index d18df4ae..b15f568c 100644 --- a/apache2/re_actions.c +++ b/apache2/re_actions.c @@ -1803,8 +1803,18 @@ static apr_status_t msre_action_exec_execute(modsec_rec *msr, apr_pool_t *mptmp, static apr_status_t msre_action_prepend_execute(modsec_rec *msr, apr_pool_t *mptmp, msre_rule *rule, msre_action *action) { - msr->content_prepend = action->param; - msr->content_prepend_len = strlen(action->param); + msc_string *var = NULL; + + /* Expand any macros in the text */ + var = apr_pcalloc(mptmp, sizeof(msc_string)); + if (var == NULL) return -1; + var->value = (char *)action->param; + var->value_len = strlen(var->value); + expand_macros(msr, var, rule, mptmp); + + /* ENH: Verify we really have to dup the data here. */ + msr->content_prepend = apr_pstrndup(msr->mp, var->value, var->value_len); + msr->content_prepend_len = var->value_len; return 1; } @@ -1813,8 +1823,18 @@ static apr_status_t msre_action_prepend_execute(modsec_rec *msr, apr_pool_t *mpt static apr_status_t msre_action_append_execute(modsec_rec *msr, apr_pool_t *mptmp, msre_rule *rule, msre_action *action) { - msr->content_append = action->param; - msr->content_append_len = strlen(action->param); + msc_string *var = NULL; + + /* Expand any macros in the text */ + var = apr_pcalloc(mptmp, sizeof(msc_string)); + if (var == NULL) return -1; + var->value = (char *)action->param; + var->value_len = strlen(var->value); + expand_macros(msr, var, rule, mptmp); + + /* ENH: Verify we really have to dup the data here. */ + msr->content_append = apr_pstrndup(msr->mp, var->value, var->value_len); + msr->content_append_len = var->value_len; return 1; } diff --git a/apache2/t/regression/action/00-misc.t b/apache2/t/regression/action/00-misc.t index 0a99b4c5..1629d697 100644 --- a/apache2/t/regression/action/00-misc.t +++ b/apache2/t/regression/action/00-misc.t @@ -1,6 +1,5 @@ ### Test misc actions -# TODO: append # TODO: block # TODO: capture # TODO: chain @@ -10,7 +9,6 @@ # TODO: initcol # TODO: multiMatch # TODO: pause -# TODO: prepend # TODO: sanitiseArg # TODO: sanitiseMatched # TODO: sanitiseRequestHeader diff --git a/apache2/t/regression/action/10-append-prepend.t b/apache2/t/regression/action/10-append-prepend.t new file mode 100644 index 00000000..97f28685 --- /dev/null +++ b/apache2/t/regression/action/10-append-prepend.t @@ -0,0 +1,49 @@ +# TODO: Need more tests here + +### append +{ + type => "action", + comment => "append content", + conf => qq( + SecRuleEngine On + SecContentInjection On + SecDebugLog "$ENV{DEBUG_LOG}" + SecDebugLogLevel 9 + SecAction "phase:1,setvar:tx.test=test" + SecAction "phase:2,append:'APPEND: \%{tx.test}'" + ), + match_log => { + debug => [ "Added content to bottom: APPEND: test", 1 ], + }, + match_response => { + status => qr/^200$/, + content => qr/APPEND: test$/, + }, + request => new HTTP::Request( + GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", + ), +}, + +### prepend +{ + type => "action", + comment => "prepend content", + conf => qq( + SecRuleEngine On + SecContentInjection On + SecDebugLog "$ENV{DEBUG_LOG}" + SecDebugLogLevel 9 + SecAction "phase:1,setvar:tx.test=test" + SecAction "phase:2,prepend:'PREPEND: \%{tx.test}'" + ), + match_log => { + debug => [ "Added content to top: PREPEND: test", 1 ], + }, + match_response => { + status => qr/^200$/, + content => qr/^PREPEND: test/, + }, + request => new HTTP::Request( + GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", + ), +}, diff --git a/doc/modsecurity2-apache-reference.xml b/doc/modsecurity2-apache-reference.xml index fff38f8b..421c33f6 100644 --- a/doc/modsecurity2-apache-reference.xml +++ b/doc/modsecurity2-apache-reference.xml @@ -4270,6 +4270,12 @@ SecAction phase:3,allow Example: SecRule RESPONSE_CONTENT_TYPE "^text/html" "nolog,pass,append:'<hr>Footer'" + + + While macro expansion is allowed in the additional content, + you are strongly cautioned against inserting user defined data + fields. +
@@ -4923,6 +4929,12 @@ SecRule REQUEST_HEADERS:User-Agent "Test" log,deny,status:403 Example: SecRule RESPONSE_CONTENT_TYPE ^text/html "phase:3,nolog,pass,prepend:'Header<br>'" + + + While macro expansion is allowed in the additional content, + you are strongly cautioned against inserting user defined data + fields. +