Skip to content

%{RULE.*} expands to an empty string in tag and some other actions and operator parameters #3742

Open

Description

@airween

Describe the bug

#3734 makes %{RULE.*} work in setvar, expirevar, msg, logdata and the dynamic collection keys, and in every kind of rule (SecRule, SecAction, SecRuleScript). Other places still expand their macros without the rule, so %{RULE.id}, %{RULE.msg} etc. are empty there, in every kind of rule:

where call
tag Tag::getName(), src/actions/tag.cc:55
initcol src/actions/init_col.cc:58
setsid, setuid, setrsc src/actions/set_sid.cc:30, set_uid.cc:30, set_rsc.cc:30
setenv src/actions/set_env.cc:30
redirect src/actions/disruptive/redirect.cc:39
operator parameters (@rx, @eq, @contains, @streq, …) m_string->evaluate(transaction) in src/operators/*.cc, and in Operator::resolveMatchMessage()

All of them call m_string->evaluate(t) instead of m_string->evaluate(t, rule).

tag is the one most likely to matter, eg. tag:'rule-%{RULE.id}' to group the log entries by rule. The others are unlikely to use %{RULE.*}, but they should behave the same.

To Reproduce

SecRuleEngine On
SecDebugLogLevel 9
SecRule ARGS:a "@streq test" "id:100,phase:1,pass,log,tag:'rule-%{RULE.id}'"
curl "http://localhost/?a=test"

Expected behavior

The debug log contains Rule tag: rule-100, and the error log entry contains [tag "rule-100"].

Actual behavior

The debug log contains Rule tag: rule-, and the error log entry contains [tag "rule-"].

Server (please complete the following information):

Additional context

  • For the actions, the fix is the same one-liner as in fix: expand %{RULE.*} in SecAction and SecRuleScript rules #3734: pass the rule, m_string->evaluate(t, rule). Tag::getName() is also called from other places, so it needs the rule as a parameter.
  • Operator parameters need more work: Operator::evaluate(Transaction *, RuleWithActions *, const std::string &, RuleMessage &) drops the rule and calls evaluate(transaction, str), so the rule has to be passed through to each operator that expands its parameter.
  • Msg::data() and LogData::data() (src/actions/msg.cc:60, src/actions/log_data.cc:40) also expand without the rule. That's intentional: fix: expand %{RULE.*} in SecAction and SecRuleScript rules #3734 keeps them unchanged for RuleWithActions::msg() and logData().
  • Each fix needs a regression case, like the ones in test/test-cases/regression/variable-RULE.json.

Related: #3733, #3734.

Activity

  1. added
    3.xRelated to ModSecurity version 3.x
    on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.xRelated to ModSecurity version 3.x

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions