pySigma-backend-sqlite 2.1.0__tar.gz → 2.1.1__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: 2.1.0
3
+ Version: 2.1.1
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.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Python :: 3.14
14
14
  Classifier: Programming Language :: Python :: 3.15
15
- Requires-Dist: pysigma (>=2.0.0,<3.0)
15
+ Requires-Dist: pysigma (>=2.0.1,<3.0)
16
16
  Project-URL: Repository, https://github.com/SigmaHQ/pySigma-backend-sqlite
17
17
  Description-Content-Type: text/markdown
18
18
 
@@ -35,9 +35,9 @@ Maintained by [wagga](https://github.com/wagga40/).
35
35
  pip install pysigma-backend-sqlite
36
36
  ```
37
37
 
38
- Requires Python 3.11+ and [pySigma](https://github.com/SigmaHQ/pySigma) 2.x.
39
- Backend 2.0.0 is the last release for pySigma 1.5. Correlation output needs
40
- SQLite 3.38 or newer.
38
+ Requires Python 3.11+ and [pySigma](https://github.com/SigmaHQ/pySigma) 2.0.1 or
39
+ newer. Correlation output needs SQLite 3.38 or newer. sigma-cli 3.1 still requires
40
+ pySigma 1.x, so alongside it pip installs backend 2.0.0, which has no keyword search.
41
41
 
42
42
  ## Quick start
43
43
 
@@ -68,35 +68,31 @@ Processing pipelines map a logsource to concrete fields. With
68
68
  SELECT * FROM logs WHERE Channel='Microsoft-Windows-Sysmon/Operational' AND (EventID=1 AND Image LIKE '%\\whoami.exe' ESCAPE '\')
69
69
  ```
70
70
 
71
- Those pipeline packages still declare `pysigma<2`; until they are updated, install
72
- them with `pip install --no-deps pysigma-pipeline-sysmon pysigma-pipeline-windows`.
73
- With sigma-cli:
71
+ The sysmon and windows pipelines still declare `pysigma<2`; install them with
72
+ `pip install --no-deps pysigma-pipeline-sysmon pysigma-pipeline-windows`. With sigma-cli:
74
73
 
75
74
  ```shell
76
75
  sigma convert -t sqlite -f zircolite -p sysmon -p windows-logsources rules/
77
76
  ```
78
77
 
79
- sigma-cli 3.1 still requires pySigma 1.x, so it installs backend 2.0.0.
80
-
81
78
  ## Output formats
82
79
 
83
80
  | Format | Output |
84
81
  |---|---|
85
82
  | `default` | One `SELECT * FROM logs WHERE ...` statement per rule |
86
- | `zircolite` | A JSON list with one entry per rule: Sigma metadata, the SQL, and what a consumer needs to run it. See [output format](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/output-format.md) |
83
+ | `zircolite` | A JSON list with one entry per rule: Sigma metadata, the SQL, and what a consumer needs to run it. See [output format](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/output-format.md) |
87
84
 
88
85
  ## Options
89
86
 
90
- Pass options as constructor keywords, or from sigma-cli with `-O name=value`.
91
- Options are read at construction; assigning attributes later skips validation
92
- and does not change the timestamp expression.
87
+ Pass options as constructor keywords, or from sigma-cli with `-O name=value`. Set
88
+ them at construction; changing attributes afterwards is unsupported.
93
89
 
94
90
  | Option | Default | Purpose |
95
91
  |---|---|---|
96
92
  | `table` | `logs` | Table to query. A pipeline `setState` on `table` takes precedence |
97
93
  | `collate_nocase` | `false` | Emit `field='value' COLLATE NOCASE` for tables without `NOCASE` columns |
98
94
  | `max_flat_operands` | `100` | Longer AND/OR chains are nested to stay under SQLite's expression depth limit |
99
- | `fulltext_field` | none | Column of searchable event text; enables [keyword search](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/keyword-search.md) |
95
+ | `fulltext_field` | none | Column of searchable event text; enables [keyword search](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/keyword-search.md) |
100
96
  | `timestamp_field` | `timestamp` | Event time column used by correlations |
101
97
  | `timestamp_format` | `iso` | `iso`, `unix`, `unix_ms` or `unix_us` |
102
98
  | `timestamp_seconds_expression` | ISO parser | SQL turning `{field}` into Unix seconds; overrides `timestamp_format` |
@@ -123,35 +119,32 @@ The SQL keeps Sigma's meaning without help from the caller:
123
119
  - **Negation.** Sigma reads a condition on a missing field as false; SQLite reads
124
120
  it as `NULL`, and `NOT NULL` drops the row. Every `NOT` therefore wraps its
125
121
  operand: `EventID=1 AND (NOT COALESCE((CommandLine LIKE '%foo%' ESCAPE '\'), 0))`.
126
- - **Case.** `LIKE` ignores case. `=` does only on `NOCASE` columns, which is how
127
- Zircolite builds its table; otherwise set `collate_nocase`. `cased` uses `GLOB`.
122
+ - **Case.** `LIKE` ignores case; `=` does only on `NOCASE` columns (Zircolite's
123
+ layout), otherwise set `collate_nocase`.
128
124
  - **Booleans.** `Flag: true` matches text or integer storage: `(Flag='true' OR Flag=1)`.
129
- - **Long lists.** Chains above `max_flat_operands` are regrouped, so rules with
130
- thousands of values don't fail with "Expression tree is too large".
131
125
  - **Field names.** SQLite keywords and names with characters other than letters,
132
126
  digits and `_` are quoted with backticks. `field: null` becomes `field IS NULL`.
133
127
 
134
128
  ## Correlations
135
129
 
136
- All Sigma correlation types run in SQLite: `event_count`, `value_count`,
137
- `value_sum`, `value_avg`, `value_median`, `value_percentile`, `temporal` and
138
- `temporal_ordered`, including chains, aliases and extended temporal conditions.
139
- Each result row is one alert occurrence with its window, metric and contributing
140
- event IDs. Semantics are described in [correlations](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/correlations.md);
141
- upgrading from backend 1.x is covered in the [migration guide](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/migration-v2.md).
130
+ All Sigma correlation types run in SQLite, including chains, aliases and extended
131
+ temporal conditions. See [correlations](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/correlations.md)
132
+ for their semantics and the [migration guide](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/migration-v2.md)
133
+ for upgrading from backend 1.x.
142
134
 
143
135
  ## Keyword search
144
136
 
145
- Keyword (fieldless) selections need a column of searchable event text:
146
- `sqliteBackend(fulltext_field="_sigma_fulltext")`. Without it, keyword rules raise
147
- an error rather than guess. See [keyword search](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/keyword-search.md).
137
+ Keyword (fieldless) rules need `fulltext_field`, a column holding each event's
138
+ searchable text. See [keyword search](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/keyword-search.md).
148
139
 
149
140
  ## Limitations
150
141
 
151
142
  - **REGEXP.** SQLite has no built-in `REGEXP`. Register one that is false for `NULL`:
152
143
  `connection.create_function("regexp", 2, lambda p, v: v is not None and re.search(p, str(v)) is not None)`.
153
- pySigma 2 validates `|re` patterns with RE2, so rules with lookarounds or
154
- backreferences are rejected when parsed.
144
+ pySigma validates `|re` with RE2 by default, rejecting lookarounds and
145
+ backreferences. For trusted rules, pass `policy=TrustedPolicy` (from
146
+ `sigma.policy.profiles`) to `SigmaCollection.from_yaml()`; the patterns must then
147
+ suit Python's `re`.
155
148
  - **CIDR.** SQLite has no network type. Prefix patterns match IPv6 addresses only
156
149
  in the spellings pySigma expands to.
157
150
  - **Case folding** (`NOCASE`, `LIKE`) is ASCII only.
@@ -160,7 +153,7 @@ an error rather than guess. See [keyword search](https://github.com/wagga40/pySi
160
153
  - **Field existence.** SQL `NULL` cannot tell a missing field from an explicit null.
161
154
  - **Multi-field `value_count`** (a list in `condition.field`) is rejected.
162
155
  - **Unknown columns.** A query naming a column the table lacks fails to prepare.
163
- Add missing columns as `NULL` first; see [output format](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/output-format.md).
156
+ Add missing columns as `NULL` first; see [output format](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/output-format.md).
164
157
 
165
158
  ## Development
166
159
 
@@ -170,7 +163,7 @@ poetry run pytest
170
163
  SQLITE_MIN_BINARY=/path/to/sqlite-3.38 poetry run pytest tests/test_sqlite_minimum.py
171
164
  ```
172
165
 
173
- `tools/audit_corpus.py` converts and prepares a SigmaHQ checkout per profile
174
- (coverage, not detection accuracy). `tools/benchmark_correlations.py` times
175
- sparse and dense correlation windows.
166
+ `tools/audit_corpus.py` converts and prepares a SigmaHQ checkout per profile (see
167
+ [coverage](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/keyword-search.md#coverage)).
168
+ `tools/benchmark_correlations.py` times sparse and dense correlation windows.
176
169
 
@@ -17,9 +17,9 @@ Maintained by [wagga](https://github.com/wagga40/).
17
17
  pip install pysigma-backend-sqlite
18
18
  ```
19
19
 
20
- Requires Python 3.11+ and [pySigma](https://github.com/SigmaHQ/pySigma) 2.x.
21
- Backend 2.0.0 is the last release for pySigma 1.5. Correlation output needs
22
- SQLite 3.38 or newer.
20
+ Requires Python 3.11+ and [pySigma](https://github.com/SigmaHQ/pySigma) 2.0.1 or
21
+ newer. Correlation output needs SQLite 3.38 or newer. sigma-cli 3.1 still requires
22
+ pySigma 1.x, so alongside it pip installs backend 2.0.0, which has no keyword search.
23
23
 
24
24
  ## Quick start
25
25
 
@@ -50,35 +50,31 @@ Processing pipelines map a logsource to concrete fields. With
50
50
  SELECT * FROM logs WHERE Channel='Microsoft-Windows-Sysmon/Operational' AND (EventID=1 AND Image LIKE '%\\whoami.exe' ESCAPE '\')
51
51
  ```
52
52
 
53
- Those pipeline packages still declare `pysigma<2`; until they are updated, install
54
- them with `pip install --no-deps pysigma-pipeline-sysmon pysigma-pipeline-windows`.
55
- With sigma-cli:
53
+ The sysmon and windows pipelines still declare `pysigma<2`; install them with
54
+ `pip install --no-deps pysigma-pipeline-sysmon pysigma-pipeline-windows`. With sigma-cli:
56
55
 
57
56
  ```shell
58
57
  sigma convert -t sqlite -f zircolite -p sysmon -p windows-logsources rules/
59
58
  ```
60
59
 
61
- sigma-cli 3.1 still requires pySigma 1.x, so it installs backend 2.0.0.
62
-
63
60
  ## Output formats
64
61
 
65
62
  | Format | Output |
66
63
  |---|---|
67
64
  | `default` | One `SELECT * FROM logs WHERE ...` statement per rule |
68
- | `zircolite` | A JSON list with one entry per rule: Sigma metadata, the SQL, and what a consumer needs to run it. See [output format](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/output-format.md) |
65
+ | `zircolite` | A JSON list with one entry per rule: Sigma metadata, the SQL, and what a consumer needs to run it. See [output format](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/output-format.md) |
69
66
 
70
67
  ## Options
71
68
 
72
- Pass options as constructor keywords, or from sigma-cli with `-O name=value`.
73
- Options are read at construction; assigning attributes later skips validation
74
- and does not change the timestamp expression.
69
+ Pass options as constructor keywords, or from sigma-cli with `-O name=value`. Set
70
+ them at construction; changing attributes afterwards is unsupported.
75
71
 
76
72
  | Option | Default | Purpose |
77
73
  |---|---|---|
78
74
  | `table` | `logs` | Table to query. A pipeline `setState` on `table` takes precedence |
79
75
  | `collate_nocase` | `false` | Emit `field='value' COLLATE NOCASE` for tables without `NOCASE` columns |
80
76
  | `max_flat_operands` | `100` | Longer AND/OR chains are nested to stay under SQLite's expression depth limit |
81
- | `fulltext_field` | none | Column of searchable event text; enables [keyword search](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/keyword-search.md) |
77
+ | `fulltext_field` | none | Column of searchable event text; enables [keyword search](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/keyword-search.md) |
82
78
  | `timestamp_field` | `timestamp` | Event time column used by correlations |
83
79
  | `timestamp_format` | `iso` | `iso`, `unix`, `unix_ms` or `unix_us` |
84
80
  | `timestamp_seconds_expression` | ISO parser | SQL turning `{field}` into Unix seconds; overrides `timestamp_format` |
@@ -105,35 +101,32 @@ The SQL keeps Sigma's meaning without help from the caller:
105
101
  - **Negation.** Sigma reads a condition on a missing field as false; SQLite reads
106
102
  it as `NULL`, and `NOT NULL` drops the row. Every `NOT` therefore wraps its
107
103
  operand: `EventID=1 AND (NOT COALESCE((CommandLine LIKE '%foo%' ESCAPE '\'), 0))`.
108
- - **Case.** `LIKE` ignores case. `=` does only on `NOCASE` columns, which is how
109
- Zircolite builds its table; otherwise set `collate_nocase`. `cased` uses `GLOB`.
104
+ - **Case.** `LIKE` ignores case; `=` does only on `NOCASE` columns (Zircolite's
105
+ layout), otherwise set `collate_nocase`.
110
106
  - **Booleans.** `Flag: true` matches text or integer storage: `(Flag='true' OR Flag=1)`.
111
- - **Long lists.** Chains above `max_flat_operands` are regrouped, so rules with
112
- thousands of values don't fail with "Expression tree is too large".
113
107
  - **Field names.** SQLite keywords and names with characters other than letters,
114
108
  digits and `_` are quoted with backticks. `field: null` becomes `field IS NULL`.
115
109
 
116
110
  ## Correlations
117
111
 
118
- All Sigma correlation types run in SQLite: `event_count`, `value_count`,
119
- `value_sum`, `value_avg`, `value_median`, `value_percentile`, `temporal` and
120
- `temporal_ordered`, including chains, aliases and extended temporal conditions.
121
- Each result row is one alert occurrence with its window, metric and contributing
122
- event IDs. Semantics are described in [correlations](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/correlations.md);
123
- upgrading from backend 1.x is covered in the [migration guide](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/migration-v2.md).
112
+ All Sigma correlation types run in SQLite, including chains, aliases and extended
113
+ temporal conditions. See [correlations](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/correlations.md)
114
+ for their semantics and the [migration guide](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/migration-v2.md)
115
+ for upgrading from backend 1.x.
124
116
 
125
117
  ## Keyword search
126
118
 
127
- Keyword (fieldless) selections need a column of searchable event text:
128
- `sqliteBackend(fulltext_field="_sigma_fulltext")`. Without it, keyword rules raise
129
- an error rather than guess. See [keyword search](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/keyword-search.md).
119
+ Keyword (fieldless) rules need `fulltext_field`, a column holding each event's
120
+ searchable text. See [keyword search](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/keyword-search.md).
130
121
 
131
122
  ## Limitations
132
123
 
133
124
  - **REGEXP.** SQLite has no built-in `REGEXP`. Register one that is false for `NULL`:
134
125
  `connection.create_function("regexp", 2, lambda p, v: v is not None and re.search(p, str(v)) is not None)`.
135
- pySigma 2 validates `|re` patterns with RE2, so rules with lookarounds or
136
- backreferences are rejected when parsed.
126
+ pySigma validates `|re` with RE2 by default, rejecting lookarounds and
127
+ backreferences. For trusted rules, pass `policy=TrustedPolicy` (from
128
+ `sigma.policy.profiles`) to `SigmaCollection.from_yaml()`; the patterns must then
129
+ suit Python's `re`.
137
130
  - **CIDR.** SQLite has no network type. Prefix patterns match IPv6 addresses only
138
131
  in the spellings pySigma expands to.
139
132
  - **Case folding** (`NOCASE`, `LIKE`) is ASCII only.
@@ -142,7 +135,7 @@ an error rather than guess. See [keyword search](https://github.com/wagga40/pySi
142
135
  - **Field existence.** SQL `NULL` cannot tell a missing field from an explicit null.
143
136
  - **Multi-field `value_count`** (a list in `condition.field`) is rejected.
144
137
  - **Unknown columns.** A query naming a column the table lacks fails to prepare.
145
- Add missing columns as `NULL` first; see [output format](https://github.com/wagga40/pySigma-backend-sqlite/blob/main/docs/output-format.md).
138
+ Add missing columns as `NULL` first; see [output format](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/output-format.md).
146
139
 
147
140
  ## Development
148
141
 
@@ -152,6 +145,6 @@ poetry run pytest
152
145
  SQLITE_MIN_BINARY=/path/to/sqlite-3.38 poetry run pytest tests/test_sqlite_minimum.py
153
146
  ```
154
147
 
155
- `tools/audit_corpus.py` converts and prepares a SigmaHQ checkout per profile
156
- (coverage, not detection accuracy). `tools/benchmark_correlations.py` times
157
- sparse and dense correlation windows.
148
+ `tools/audit_corpus.py` converts and prepares a SigmaHQ checkout per profile (see
149
+ [coverage](https://github.com/SigmaHQ/pySigma-backend-sqlite/blob/main/docs/keyword-search.md#coverage)).
150
+ `tools/benchmark_correlations.py` times sparse and dense correlation windows.
@@ -1,8 +1,8 @@
1
1
  [project]
2
2
  name = "pySigma-backend-sqlite"
3
- version = "2.1.0"
3
+ version = "2.1.1"
4
4
  requires-python = ">=3.11,<4.0"
5
- dependencies = ["pysigma>=2.0.0,<3.0"]
5
+ dependencies = ["pysigma>=2.0.1,<3.0"]
6
6
  description = "pySigma sqlite backend"
7
7
  readme = "README.md"
8
8
  authors = [
@@ -16,18 +16,20 @@ packages = [
16
16
  ]
17
17
 
18
18
  [tool.poetry.group.dev.dependencies]
19
- black = "^24.1"
20
19
  pytest = "^8.0"
21
- pytest-cov = "^4.1"
20
+ pytest-cov = "^7.1"
22
21
  coverage = "^7.4"
22
+ ruff = "^0.16.10"
23
23
 
24
24
 
25
25
  [tool.pytest.ini_options]
26
26
  testpaths = ["tests"]
27
- filterwarnings = [
28
- # Suppress pyparsing deprecation warning from pySigma library
29
- "ignore:'parseString' deprecated:DeprecationWarning",
30
- ]
27
+
28
+ [tool.ruff]
29
+ target-version = "py311"
30
+
31
+ [tool.ruff.lint]
32
+ select = ["E4", "E7", "E9", "F", "I", "UP"]
31
33
 
32
34
  [build-system]
33
35
  requires = ["poetry-core>=2.0.0"]