Island: Fix a ZT multiple findings bug

A bug happened in zero trust findings: since multiple exploiters run at the same time, they send telemetries at the same time and those telemetries get parsed at the same time. So multiple threads fetch ZT findings at once, finds none and creates duplicate findings. With this bugfix only one thread can fetch for findings at a time. This means that one thread creates the finding and others fetch it and just add events to it
This commit is contained in:
vakaris_zilius 2022-03-14 13:16:41 +00:00
parent 14953c8cdd
commit 29e494cfb1
1 changed files with 15 additions and 9 deletions

View File

@ -1,6 +1,7 @@
from typing import List
from bson import ObjectId
from gevent.lock import BoundedSemaphore
from common.common_consts import zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event
@ -9,6 +10,10 @@ from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFind
class MonkeyZTFindingService:
# Required to synchronize db state between different threads
_finding_lock = BoundedSemaphore()
@staticmethod
def create_or_add_to_existing(test: str, status: str, events: List[Event]):
"""
@ -20,16 +25,17 @@ class MonkeyZTFindingService:
the query - this is not
when this function should be used.
"""
existing_findings = list(MonkeyFinding.objects(test=test, status=status))
assert len(existing_findings) < 2, "More than one finding exists for {}:{}".format(
test, status
)
with MonkeyZTFindingService._finding_lock:
existing_findings = list(MonkeyFinding.objects(test=test, status=status))
assert len(existing_findings) < 2, "More than one finding exists for {}:{}".format(
test, status
)
if len(existing_findings) == 0:
MonkeyZTFindingService.create_new_finding(test, status, events)
else:
# Now we know for sure this is the only one
MonkeyZTFindingService.add_events(existing_findings[0], events)
if len(existing_findings) == 0:
MonkeyZTFindingService.create_new_finding(test, status, events)
else:
# Now we know for sure this is the only one
MonkeyZTFindingService.add_events(existing_findings[0], events)
@staticmethod
def create_new_finding(test: str, status: str, events: List[Event]):