Repository navigation
Conversation
With data_model output, an OR-ed regex is evaluated after tstats by rex/eval, but the <field>Condition variable was also referenced in the tstats WHERE clause, where it does not exist. Events matching only the regex branch never left tstats. Only keep the top-level conjuncts that do not reference such a variable in the tstats WHERE clause (omitting it when none remain); the full expression is still applied by the trailing search. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The change is narrowly scoped, aligns with the stated failure mode, and is backed by focused regression tests covering both end-to-end query output and the new helper’s edge cases.
Review effort: Lite
Findings: None
What changed in this PR
Fixes Splunk data model (tstats) query generation for Sigma rules that use an OR-ed regex branch: eval-only <field>Condition… variables are no longer referenced inside the tstats … where clause (where they don’t exist), preventing regex-only-matching events from being dropped before the deferred rex/eval/search stage.
Changes:
- Update
finalize_query_data_modelto striptstatsWHERE conjuncts that reference deferred OR-regex condition variables, and omitwhereentirely when nothing safe remains. - Add
_data_model_where_without_fieldshelper to conservatively keep only safe top-level conjuncts fortstatspre-filtering. - Expand tests to cover top-level OR regex behavior, mixed conjunct retention (IN/NOT kept, regex disjunction dropped), and helper parsing cases.
| File | Description |
|---|---|
sigma/backends/splunk/splunk.py |
Ensures tstats WHERE does not reference eval-only *Condition* fields and omits WHERE when empty, while preserving full logic in the trailing ` |
tests/test_backend_splunk.py |
Updates an existing expectation and adds targeted regression/unit tests for OR-regex data model query correctness and the new helper behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BLUF
data_modeloutput, an OR-ed regex is matched aftertstatsbyrex/eval, but the eval-created<field>Conditionvariable was also referenced inside thetstats … whereclause.tstatsdoes not know that variable, so a regex branch that is ORed with other conditions could never match there. Events that match only the regex were dropped before therex/eval/searchstage ran.tstatsWHERE clause keeps only the top-level conjuncts that do not reference such a variable, and is omitted when none remain. The trailing| searchstill applies the full expression.tstatspre-filter for these rules only. Rules without an OR-ed regex produce the same output as before.Priority: medium
Details
finalize_query_data_modelmoves therex/evalpipeline aftertstatsand re-applies the search expression with| search. The same expression was still used as thetstatsWHERE clause. For example,CommandLine|re OR Imagewithsplunk_cim_data_model()gives:processConditiononly exists after theeval, so insidetstatsthe WHERE clause reduces toProcesses.process_path="x.exe". An event whoseprocessmatches the regex but whoseprocess_pathis different matches the Sigma rule, yet it never leaveststats.finish_queryalready records the names of these variables instate.processing_state["deferred_or_condition_fields"]. The new helper_data_model_where_without_fieldsworks as follows:NOT xandfield IN (…)each count as one conjunct. An expression with a top-levelORis treated as a single conjunct.The remaining conjuncts are implied by the full expression, so they are a safe pre-filter. When nothing remains, the
wherekeyword is left out, because WHERE is optional intstats.After the fix, the example above has no
tstatsWHERE clause, and the existing testtest_splunk_data_model_process_creation_with_or_regexnow pre-filters onProcesses.parent_process_path="*explorer.exe"only.Changed test expectation
test_splunk_data_model_process_creation_with_or_regex: thetstatsWHERE clause no longer contains(Processes.process="*test_value*" OR processCondition="true"). With that clause, only events containingtest_valuereached the regex stage, so events matching onlyfoo.*barwere lost. The trailing| searchis unchanged.Testing
regex OR fieldrule indata_modeloutput (exact query, no WHERE clause)INandNOTconjuncts stay intstatsand the regex disjunction is removedNOT … IN (…), numbered…Condition2variables and quoted valuespytest148 passed, with Python 3.12 and pySigma 1.2.0 frompoetry.lock, run the same way as CI (poetry install+pytest).black==24.1.1(pre-commit pin) reports nothing on the changed code.🤖 Generated with Claude Code