Skip to content

%{RULE.*} expands to an empty string in SecAction and SecRuleScript #3733

Open

Description

@airween

Describe the bug

In a SecAction or a SecRuleScript rule, a %{RULE.id} macro (and any other %{RULE.*} field) expands to an empty string. In a SecRule it works.

RunTimeString::evaluate() (src/run_time_string.cc:62), which expands the macros, casts the rule to RuleWithOperator:

// FIXME: This cast should be removed.
RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(r);
z->m_var->evaluate(t, rr, &l);

SecAction is a RuleUnconditional and SecRuleScript is a RuleScript. Both derive from RuleWithActions, not from RuleWithOperator, so the cast returns NULL, and the RULE variable has no rule to read from. Variable::evaluate() takes a RuleWithActions * (src/variables/variable.h), so the cast isn't needed for the RULE variable at all.

SetVar::evaluate() has the same cast for the =+ and =- operations (src/actions/set_var.cc:104).

From reading the code, every action that expands macros through RunTimeString is affected in these rules, for example msg and logdata, not only setvar. I've only tested setvar.

The cast came in with a refactoring in v3.0.5 (59d4268, "Refactoring: renames Rule to RuleWithOperator").

Logs and dumps

SecAction, debug log:

(Rule: 108) Executing unconditional rule...
Running [independent] (non-disruptive) action: setvar
Saving variable: TX:rule_id with value: 

SecRuleScript, debug log:

 Executing script: test-cases/data/lua-getvar-tx-rule-id.lua.
Running [independent] (non-disruptive) action: setvar
Saving variable: TX:rule_id with value: 

To Reproduce

SecAction "id:108,phase:2,pass,setvar:tx.rule_id=%{RULE.id}"
SecRuleScript /path/to/script.lua "id:107,phase:2,pass,setvar:tx.rule_id=%{RULE.id}"

TX:rule_id is empty after both rules. With the same actions in a SecRule, for example SecRule ARGS:param1 "@streq value1" "id:109,phase:2,pass,setvar:tx.rule_id=%{RULE.id}", it is 109.

Expected behavior

%{RULE.id} expands to the id of the rule, 108 and 107 above, as it does in a SecRule.

Server (please complete the following information):

  • ModSecurity version (and connector): current v3/master (1ebdc39), reproduced with test/regression_tests
  • WebServer: n/a
  • OS (and distro): Debian sid

Rule Set (please complete the following information):

  • Running any public or commercial rule set? No
  • What is the version number? n/a

Additional context

CRS isn't affected: no SecAction in CRS 4.8 uses a %{rule.*} macro.

Found while checking a documentation note for #2527 (owasp-modsecurity/documentation#6).

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