Skip to content

fix: do not log multiMatch chain starters before the chain completes - #3698

Open
fzipi wants to merge 1 commit into
owasp-modsecurity:v3/masterfrom
fzipi:v3/issue-2672-multimatch-chain-auditlog
Open

fzipi wants to merge 1 commit into
owasp-modsecurity:v3/masterfrom
fzipi:v3/issue-2672-multimatch-chain-auditlog

Conversation

@fzipi

@fzipi fzipi commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

What

A chain starter with multiMatch logged every matching value as soon as its operator matched, before the chained rules ran. The message landed in Transaction::m_rulesMessages and went through the server log callback, so with SecAuditEngine RelevantOnly a request that matched only the first rule of the chain was still saved to the audit log. Rules without multiMatch were already deferred to the end of the chain.

The per-match messages of a chained rule are now kept in a local list inside RuleWithOperator::evaluate and handed to the transaction only when the whole chain has matched. A failed chain drops them. Rules that are not chained, and the last rule of a chain, keep logging each match immediately as before.

Why

Fixes #2672. CRS 942131 (multiMatch + chain) hits this path, so every request that trips only its first rule is written to the audit log under RelevantOnly.

Tests

test/test-cases/regression/issue-2672.json (registered in test/test-suite.in):

  • chain fails after the multiMatch starter matched: status 200 and "Return code 200' is not interesting to audit logs". Fails on v3/master`, passes with this change.
  • chain completes: status 403, the audit log carries the starter's msg.

Full make check on macOS with YAJL, PCRE2 and LMDB: 5113 passed, 0 failed, 20 skipped. The existing chained multiMatch cases in auditlog.json still pass.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Corrected audit logging for chained rules that match multiple times. Messages are now recorded only when the full rule chain succeeds, preventing incomplete matches from producing misleading audit entries.
    • Added regression coverage for incomplete chains and successful chains, including cases involving lowercase transformations.

A chain starter with `multiMatch` logged every matching value as soon
as the operator matched, through the per-match branch of
`RuleWithActions::performLogging`. That pushed the message into
`Transaction::m_rulesMessages` and called the server log callback
before the chained rules had been evaluated, so with
`SecAuditEngine RelevantOnly` a request that matched only the first
rule of the chain was still saved to the audit log (CRS 942131 hits
this). Rules without `multiMatch` were already deferred until the end
of the chain.

Keep the per-match messages of a chained rule in a local list and hand
them to the transaction in `RuleWithOperator::evaluate` only when the
chain has matched; a failed chain drops them. Rules that are not
chained, and the last rule of a chain, keep logging immediately.

Fixes owasp-modsecurity#2672.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tz1sULBvqAwnRreKh5eC9h
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 272ab172-c81f-4a84-9fb0-6ed353c6fdb7
📥 Commits

Reviewing files that changed from the base of the PR and between 84b5996 and 4faa2e0.

📒 Files selected for processing: 3
  • src/rule_with_operator.cc
  • test/test-cases/regression/issue-2672.json
  • test/test-suite.in

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Walkthrough

Chained multi-match rule messages are now deferred until the chain succeeds. Regression cases cover incomplete and successful chains, and the test suite includes them.

Changes: Chained multi-match logging

Layer / File(s) Summary
Defer messages until chain completion
src/rule_with_operator.cc
RuleWithOperator::evaluate saves eligible multi-match messages from chained rules. On successful chain completion, it adds them to m_rulesMessages and sends non-disruptive messages to serverLog.
Verify chained multi-match logging
test/test-cases/regression/issue-2672.json, test/test-suite.in
Regression cases check that an incomplete chain does not produce the described audit log entry and that a successful chain logs the chain starter message. The test suite includes the new cases.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: zimmerle, airween

Merge Risk: ⚪ Minimal · up to 4faa2

The change addresses audit logging for incomplete chains, and no merge-blocking issue is established. Normal checks remain appropriate before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (2 skipped: 2 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: delaying logs for multiMatch chain starters until the chain completes.
Linked Issues check Passed The changes meet issue #2672. RuleWithOperator::evaluate stores multiMatch messages for a chained rule in pendingMessages and commits them only at the full-chain success path. A failed chain ret…
Out of Scope Changes check Passed The changed source code implements the issue #2672 logging behavior. The new regression cases and test-suite registration verify that behavior. No unrelated change is present in the reviewed diff.
Full details: Linked Issues check

Explanation

The changes meet issue #2672. RuleWithOperator::evaluate stores multiMatch messages for a chained rule in pendingMessages and commits them only at the full-chain success path. A failed chain returns before that commit. The regression test covers both the failed-chain audit decision and the successful-chain message.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@airween airween added the 3.x Related to ModSecurity version 3.x label Oct 16, 2026

This branch has not been deployed

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

Labels

3.x Related to ModSecurity version 3.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rules with both chain and multiMatch may produce excess writes to audit log

2 participants