Skip to content

Commit a9e8d4e

Browse files
authored
Merge pull request #2500 from certtools/sieve-extra-dict
sieve expert bugfix: for string matching, convert value to string first
2 parents e4c42bb + cb1b8d8 commit a9e8d4e

File tree

6 files changed

+35
-2
lines changed

6 files changed

+35
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
- `intelmq.bots.parsers.dataplane.parser`: Use ` | ` as field delimiter, fix parsing of AS names including `|` (PR#2488 by DigitalTrustCenter).
3333

3434
#### Experts
35+
- `intelmq.bots.experts.sieve.expert`:
36+
- For `:contains`, `=~` and `!~`, convert the value to string before matching avoiding an exception. If the value is a dict, convert the value to JSON (PR#2500 by Sebastian Wagner).
3537

3638
#### Outputs
3739
- `intelmq.bots.outputs.misp.output_feed`: Handle failures if saved current event wasn't saved or is incorrect (PR by Kamil Mankowski).

docs/user/bots.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3586,10 +3586,12 @@ if :exists source.fqdn { ... }
35863586
if feed.name != 'acme-security' || feed.accuracy == 100 || extra.false_positive == false { ... }
35873587
```
35883588

3589-
- `:contains` matches on substrings.
3589+
- `:contains` matches on substrings ([`str.find`](https://docs.python.org/3/library/stdtypes.html#str.find)).
35903590

35913591
- `=~` matches strings based on the given regular expression. `!~` is the inverse regular expression match.
35923592

3593+
- For `:contains`, `=~` and `!~`, the value is converted to string before matching. If the value is a dict, convert the value to JSON.
3594+
35933595
- Numerical comparisons are evaluated with `<`, `<=`, `>`, `>=`.
35943596

35953597
- `<<` matches if an IP address is contained in the specified network range:

intelmq/bots/experts/sieve/expert.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import operator
1717

1818
from datetime import datetime, timedelta, timezone
19+
from json import dumps
1920
from typing import Callable, Dict, Optional, Union
2021
from enum import Enum, auto
2122

@@ -272,7 +273,14 @@ def process_single_string_match(self, key, op, value, event) -> bool:
272273
if key not in event:
273274
return op in {'!=', '!~'}
274275

275-
return self._string_op_map[op](event[key], value.value)
276+
lhs = event[key]
277+
if not isinstance(lhs, str) and op not in ('==', '!='):
278+
if isinstance(lhs, dict):
279+
lhs = dumps(lhs)
280+
else:
281+
lhs = str(lhs)
282+
283+
return self._string_op_map[op](lhs, value.value)
276284

277285
def process_multi_string_match(self, key, op, value, event) -> bool:
278286
if key not in event:

intelmq/tests/bots/experts/sieve/test_expert.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,14 @@ def test_empty_list(self):
17381738
self.run_bot()
17391739
self.assertMessageEqual(0, expected)
17401740

1741+
def test_extra_dict(self):
1742+
self.sysconfig['file'] = os.path.join(os.path.dirname(__file__), 'test_sieve_files/test_extra_dict.sieve')
1743+
event = EXAMPLE_INPUT.copy()
1744+
event['extra.some_dict'] = {'key': []}
1745+
self.input_message = event
1746+
self.run_bot()
1747+
self.assertOutputQueueLen(0)
1748+
17411749

17421750
if __name__ == '__main__': # pragma: no cover
17431751
unittest.main()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// '{"extra.some_dict": { "key": [] }}'
2+
3+
if :notexists extra.some_dict {
4+
drop
5+
}
6+
if extra.some_dict !~ '"key": ' {
7+
drop
8+
}
9+
if extra.some_dict =~ '"key": \[\]' {
10+
drop
11+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SPDX-FileCopyrightText: 2024 Bundesamt für Sicherheit in der Informationstechnik (BSI), Software engineering by Intevation GmbH
2+
SPDX-License-Identifier: AGPL-3.0-or-later

0 commit comments

Comments
 (0)