v.0.11.4
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import base64
|
||||
import os
|
||||
import tempfile
|
||||
from unittest.mock import patch
|
||||
|
||||
from app.ndr import NDRAnalyzer, ThreatIntelManager
|
||||
from app.store import AlertStore
|
||||
@@ -142,3 +143,52 @@ def test_repeated_ip_mac_changes_escalate_to_network_spoofing_and_anomalies_are_
|
||||
events = store.ndr_incident_events(int(anomaly_incident["id"]), 20)
|
||||
assert sum(1 for event in events if event["stage"] == "protocol-anomaly") == 1
|
||||
store.close()
|
||||
|
||||
|
||||
def test_baseline_touch_is_cached_for_repeated_values():
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
store = AlertStore(os.path.join(td, "ids.db"))
|
||||
ti = ThreatIntelManager(store, os.path.join(td, "suricata"))
|
||||
analyzer = NDRAnalyzer(
|
||||
store, ti, DummyRouterOS(), "192.168.88.0/24", "", "1h",
|
||||
enabled=True, auto_block=False,
|
||||
)
|
||||
calls = 0
|
||||
original = store.baseline_touch
|
||||
|
||||
def counted(*args, **kwargs):
|
||||
nonlocal calls
|
||||
calls += 1
|
||||
return original(*args, **kwargs)
|
||||
|
||||
store.baseline_touch = counted
|
||||
record = {
|
||||
"timestamp": "2026-08-15T08:20:00+00:00",
|
||||
"type": "flow", "direction": "outbound", "src_ip": "192.168.88.50",
|
||||
"dest_ip": "203.0.113.20", "dest_port": 443, "app_proto": "tls",
|
||||
}
|
||||
for _ in range(10):
|
||||
analyzer._process(dict(record), None)
|
||||
assert calls == 2 # app + outbound port, only on first sight in this process
|
||||
assert analyzer.status()["state_entries"]["baseline_lru"] == 2
|
||||
store.close()
|
||||
|
||||
|
||||
def test_beacon_state_is_bounded():
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
store = AlertStore(os.path.join(td, "ids.db"))
|
||||
ti = ThreatIntelManager(store, os.path.join(td, "suricata"))
|
||||
analyzer = NDRAnalyzer(
|
||||
store, ti, DummyRouterOS(), "192.168.88.0/24", "", "1h",
|
||||
enabled=True, auto_block=False,
|
||||
)
|
||||
with patch("app.ndr.NDR_BEACON_MAX_KEYS", 32):
|
||||
for idx in range(64):
|
||||
analyzer._behavior({
|
||||
"timestamp": "2026-08-15T08:30:00+00:00",
|
||||
"type": "flow", "direction": "outbound",
|
||||
"src_ip": "192.168.88.60", "dest_ip": f"203.0.113.{idx}",
|
||||
"dest_port": 443,
|
||||
}, None, "192.168.88.60")
|
||||
assert len(analyzer._beacon) == 32
|
||||
store.close()
|
||||
|
||||
Reference in New Issue
Block a user