pySigma-backend-sqlite 1.1.3__tar.gz → 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pySigma-backend-sqlite
3
- Version: 1.1.3
3
+ Version: 1.2.0
4
4
  Summary: pySigma sqlite backend
5
5
  License-Expression: LGPL-3.0-only
6
6
  License-File: LICENSE
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
13
  Classifier: Programming Language :: Python :: 3.13
14
14
  Classifier: Programming Language :: Python :: 3.14
15
- Requires-Dist: pysigma (>=1.0.2,<=2.0)
15
+ Requires-Dist: pysigma (>=1,<2)
16
16
  Project-URL: Repository, https://github.com/SigmaHQ/pySigma-backend-sqlite
17
17
  Description-Content-Type: text/markdown
18
18
 
@@ -35,6 +35,11 @@ This backend is currently maintained by:
35
35
 
36
36
  * [wagga](https://github.com/wagga40/)
37
37
 
38
+ ## Requirements
39
+
40
+ * Python 3.10 or later
41
+ * [pySigma](https://github.com/SigmaHQ/pySigma) `>= 1.0.2, < 2.0` (tested with 1.4.0)
42
+
38
43
  ## Supported Features
39
44
 
40
45
  ### Sigma Modifiers
@@ -51,8 +56,11 @@ This backend is currently maintained by:
51
56
  | `fieldref` | Compare two fields | `field1=field2` or with `LIKE` for startswith/endswith/contains |
52
57
  | `exists` | Field existence check | `field = field` |
53
58
  | `gt`, `gte`, `lt`, `lte` | Numeric comparisons | `>`, `>=`, `<`, `<=` |
59
+ | `neq` | Not equal | `NOT field='value'` |
54
60
  | `hour`, `minute`, `day`, `week`, `month`, `year` | Timestamp part extraction | `strftime()` |
55
61
 
62
+ > **Note on `cased`:** SQLite's `GLOB` is a native 2-argument operator with no `ESCAPE` clause, so queries are emitted as `field GLOB 'pattern'` and backslashes are kept literal (e.g. Windows paths match as-is). Because `GLOB` has no escape mechanism, a *literal* `*`, `?` or `[` inside a `cased` value is still interpreted as a glob metacharacter; escaping such literals (`[*]`) is not currently supported.
63
+
56
64
  ### Correlation Rules
57
65
 
58
66
  The backend supports Sigma correlation rules with the following types:
@@ -65,6 +73,10 @@ The backend supports Sigma correlation rules with the following types:
65
73
  | `temporal_ordered` | Events occurring in a specific order within a timespan |
66
74
  | `value_sum` | Sum of field values |
67
75
  | `value_avg` | Average of field values |
76
+ | `value_percentile` | Percentile of field values |
77
+ | `value_median` | Median of field values |
78
+
79
+ The following correlation types are **not supported**: `temporal_extended`, `temporal_ordered_extended`.
68
80
 
69
81
  Correlation rules support `group-by` for grouping results and `timespan` for temporal constraints.
70
82
 
@@ -120,9 +132,9 @@ poetry add pysigma-pipeline-windows
120
132
 
121
133
  ### Convert a rule
122
134
 
123
- ```python
135
+ ```python
124
136
  from sigma.collection import SigmaCollection
125
- from sigma.backends.sqlite import sqlite
137
+ from sigma.backends.sqlite import sqliteBackend
126
138
  from sigma.pipelines.sysmon import sysmon_pipeline
127
139
  from sigma.pipelines.windows import windows_logsource_pipeline
128
140
 
@@ -134,7 +146,7 @@ from sigma.pipelines.windows import windows_logsource_pipeline
134
146
  # For process_creation/windows, this produces:
135
147
  # Channel='Microsoft-Windows-Sysmon/Operational' AND EventID=1
136
148
  combined_pipeline = sysmon_pipeline() + windows_logsource_pipeline()
137
- sqlite_backend = sqlite.sqliteBackend(combined_pipeline)
149
+ sqlite_backend = sqliteBackend(combined_pipeline)
138
150
  # Set the table name for the generated SQL queries
139
151
  sqlite_backend.table = "logs"
140
152
 
@@ -17,6 +17,11 @@ This backend is currently maintained by:
17
17
 
18
18
  * [wagga](https://github.com/wagga40/)
19
19
 
20
+ ## Requirements
21
+
22
+ * Python 3.10 or later
23
+ * [pySigma](https://github.com/SigmaHQ/pySigma) `>= 1.0.2, < 2.0` (tested with 1.4.0)
24
+
20
25
  ## Supported Features
21
26
 
22
27
  ### Sigma Modifiers
@@ -33,8 +38,11 @@ This backend is currently maintained by:
33
38
  | `fieldref` | Compare two fields | `field1=field2` or with `LIKE` for startswith/endswith/contains |
34
39
  | `exists` | Field existence check | `field = field` |
35
40
  | `gt`, `gte`, `lt`, `lte` | Numeric comparisons | `>`, `>=`, `<`, `<=` |
41
+ | `neq` | Not equal | `NOT field='value'` |
36
42
  | `hour`, `minute`, `day`, `week`, `month`, `year` | Timestamp part extraction | `strftime()` |
37
43
 
44
+ > **Note on `cased`:** SQLite's `GLOB` is a native 2-argument operator with no `ESCAPE` clause, so queries are emitted as `field GLOB 'pattern'` and backslashes are kept literal (e.g. Windows paths match as-is). Because `GLOB` has no escape mechanism, a *literal* `*`, `?` or `[` inside a `cased` value is still interpreted as a glob metacharacter; escaping such literals (`[*]`) is not currently supported.
45
+
38
46
  ### Correlation Rules
39
47
 
40
48
  The backend supports Sigma correlation rules with the following types:
@@ -47,6 +55,10 @@ The backend supports Sigma correlation rules with the following types:
47
55
  | `temporal_ordered` | Events occurring in a specific order within a timespan |
48
56
  | `value_sum` | Sum of field values |
49
57
  | `value_avg` | Average of field values |
58
+ | `value_percentile` | Percentile of field values |
59
+ | `value_median` | Median of field values |
60
+
61
+ The following correlation types are **not supported**: `temporal_extended`, `temporal_ordered_extended`.
50
62
 
51
63
  Correlation rules support `group-by` for grouping results and `timespan` for temporal constraints.
52
64
 
@@ -102,9 +114,9 @@ poetry add pysigma-pipeline-windows
102
114
 
103
115
  ### Convert a rule
104
116
 
105
- ```python
117
+ ```python
106
118
  from sigma.collection import SigmaCollection
107
- from sigma.backends.sqlite import sqlite
119
+ from sigma.backends.sqlite import sqliteBackend
108
120
  from sigma.pipelines.sysmon import sysmon_pipeline
109
121
  from sigma.pipelines.windows import windows_logsource_pipeline
110
122
 
@@ -116,7 +128,7 @@ from sigma.pipelines.windows import windows_logsource_pipeline
116
128
  # For process_creation/windows, this produces:
117
129
  # Channel='Microsoft-Windows-Sysmon/Operational' AND EventID=1
118
130
  combined_pipeline = sysmon_pipeline() + windows_logsource_pipeline()
119
- sqlite_backend = sqlite.sqliteBackend(combined_pipeline)
131
+ sqlite_backend = sqliteBackend(combined_pipeline)
120
132
  # Set the table name for the generated SQL queries
121
133
  sqlite_backend.table = "logs"
122
134
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pySigma-backend-sqlite"
3
- version = "1.1.3"
3
+ version = "1.2.0"
4
4
  description = "pySigma sqlite backend"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -15,7 +15,7 @@ packages = [
15
15
 
16
16
  [tool.poetry.dependencies]
17
17
  python = "^3.10"
18
- pysigma = ">=1.0.2,<=2.0"
18
+ pysigma = "^1"
19
19
 
20
20
  [tool.poetry.group.dev.dependencies]
21
21
  black = "^24.1"
@@ -144,7 +144,12 @@ class sqliteBackend(TextQueryBackend):
144
144
  # remove it from re_flags or don't define it to ensure proper error handling in case of appearance.
145
145
  # re_flags : Dict[SigmaRegularExpressionFlag, str] = {}
146
146
 
147
- case_sensitive_match_expression: ClassVar[str] = "{field} GLOB {value} ESCAPE '\\'"
147
+ # SQLite's GLOB is a 2-argument operator with no ESCAPE clause (unlike LIKE);
148
+ # emitting "ESCAPE '\'" triggers "wrong number of arguments to function GLOB()" at runtime.
149
+ # Wildcards for |startswith/|endswith/|contains|cased are embedded in the value via
150
+ # case_sensitive_match_expression; dedicated startswith/endswith/contains templates
151
+ # would place GLOB metacharacters outside the quoted literal and produce invalid SQL.
152
+ case_sensitive_match_expression: ClassVar[str] = "{field} GLOB {value}"
148
153
 
149
154
  # Numeric comparison operators
150
155
  compare_op_expression: ClassVar[str] = (
@@ -449,7 +454,9 @@ class sqliteBackend(TextQueryBackend):
449
454
  escape_char=self.escape_char,
450
455
  wildcard_multi=self.wildcard_glob,
451
456
  wildcard_single=self.wildcard_glob_single,
452
- add_escaped=self.add_escaped,
457
+ # GLOB has no ESCAPE clause, so backslashes must stay literal.
458
+ # Escaping them (as LIKE requires) would break matches like Windows paths.
459
+ add_escaped="",
453
460
  filter_chars=self.filter_chars,
454
461
  )
455
462
  else:
@@ -540,7 +547,7 @@ class sqliteBackend(TextQueryBackend):
540
547
  def convert_condition_field_eq_val_str_case_sensitive(
541
548
  self, cond: ConditionFieldEqualsValueExpression, state: ConversionState
542
549
  ) -> Union[str, DeferredQueryExpression]:
543
- """Conversion of case-sensitive field = string value expressions"""
550
+ """Case-sensitive matching via GLOB with literal backslashes (no ESCAPE clause)."""
544
551
  try:
545
552
  if ( # Check conditions for usage of 'startswith' operator
546
553
  self.case_sensitive_startswith_expression