Skip to content

Support nested RULE macros in RULE.msg and RULE.logdata with safe recursion handling #3735

Open

Description

@coderabbitai

Summary

Add rule-aware nested macro expansion when %{RULE.msg} or %{RULE.logdata} resolves a message or logdata string that itself contains %{RULE.*}.

This is a follow-up requested by @airween. It is separate from PR #3734, which fixes direct action expansion in Msg::evaluate() and LogData::evaluate().

Current behavior and rationale

As discussed in the linked review, RuleWithActions::msg() and RuleWithActions::logData() call their action's data() method without the current rule context. Nested %{RULE.*} fields therefore expand to empty values. For example, reading %{RULE.msg} for a message containing %{RULE.id} loses the nested rule ID.

Passing the rule context without recursion handling can cause unbounded recursion for self-references such as a message containing %{RULE.msg}. Cross-references between message and logdata also need defined behavior.

Required changes

  • Define the expected behavior for nested expansion and recursive references.
  • Propagate the current rule through RuleWithActions::msg() / RuleWithActions::logData() and Msg::data() / LogData::data().
  • Design recursion handling that terminates direct and indirect cycles without suppressing valid non-recursive expansion.
  • Keep evaluation safe when multiple transactions and threads use shared rule objects. Do not introduce unsynchronized mutable evaluation state on shared rules.
  • Preserve the direct action expansion fixed in PR fix: expand %{RULE.*} in SecAction and SecRuleScript rules #3734.
  • Add regression coverage and document the selected recursion behavior.

The recursion mechanism remains a design choice; this issue does not prescribe the earlier proposed thread-local guard.

Affected areas

  • src/rule_with_actions.cc
  • src/actions/msg.h and src/actions/msg.cc
  • src/actions/log_data.h and src/actions/log_data.cc
  • src/variables/rule.h
  • src/run_time_string.cc
  • test/test-cases/regression/variable-RULE.json

Acceptance criteria

  • Reading %{RULE.msg} or %{RULE.logdata} preserves the current rule for nested non-recursive fields such as %{RULE.id}.
  • Direct self-references and message/logdata cycles terminate with a documented result.
  • Repeated valid expansions do not retain stale recursion state.
  • Concurrent transactions using the same rule do not interfere with each other's expansion.
  • Existing direct msg and logdata expansion remains unchanged.
  • Regression cases cover nested expansion, self-reference, and cross-reference cycles.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions