diff --git a/monkey/monkey_island/cc/models/utils/field_types/field_type_abc.py b/monkey/monkey_island/cc/models/utils/field_types/field_type_abc.py new file mode 100644 index 000000000..c2d87ff92 --- /dev/null +++ b/monkey/monkey_island/cc/models/utils/field_types/field_type_abc.py @@ -0,0 +1,14 @@ +from abc import ABC, abstractmethod +from typing import Any + + +class FieldTypeABC(ABC): + @staticmethod + @abstractmethod + def encrypt(value: Any): + raise NotImplementedError() + + @staticmethod + @abstractmethod + def decrypt(value: Any): + raise NotImplementedError() diff --git a/monkey/monkey_island/cc/models/utils/field_types/string_list.py b/monkey/monkey_island/cc/models/utils/field_types/string_list.py new file mode 100644 index 000000000..39e8888e7 --- /dev/null +++ b/monkey/monkey_island/cc/models/utils/field_types/string_list.py @@ -0,0 +1,14 @@ +from typing import List + +from monkey_island.cc.models.utils.field_types.field_type_abc import FieldTypeABC +from monkey_island.cc.server_utils.encryption import string_encryptor + + +class StringList(FieldTypeABC): + @staticmethod + def encrypt(value: List[str]): + return [string_encryptor.encrypt(string) for string in value] + + @staticmethod + def decrypt(value: List[str]): + return [string_encryptor.decrypt(string) for string in value] diff --git a/monkey/monkey_island/cc/models/utils/report_encryptor.py b/monkey/monkey_island/cc/models/utils/report_encryptor.py new file mode 100644 index 000000000..93f8bdd03 --- /dev/null +++ b/monkey/monkey_island/cc/models/utils/report_encryptor.py @@ -0,0 +1,48 @@ +from dataclasses import dataclass +from typing import Callable, Type + +import dpath.util + +from monkey_island.cc.models.utils.field_types.field_type_abc import FieldTypeABC +from monkey_island.cc.models.utils.field_types.string_list import StringList + + +@dataclass +class SensitiveField: + path: str + path_separator = "." + field_type: Type[FieldTypeABC] + + +sensitive_fields = [SensitiveField(path="overview.config_passwords", field_type=StringList)] + + +def encrypt(report: dict) -> dict: + for sensitive_field in sensitive_fields: + _apply_operation_to_report_field( + report, sensitive_field, sensitive_field.field_type.encrypt + ) + + return report + + +def decrypt(report: dict) -> dict: + for sensitive_field in sensitive_fields: + _apply_operation_to_report_field( + report, sensitive_field, sensitive_field.field_type.decrypt + ) + return report + + +def _apply_operation_to_report_field( + report: dict, sensitive_field: SensitiveField, operation: Callable +): + field_value = dpath.util.get(report, sensitive_field.path, sensitive_field.path_separator, None) + if field_value is None: + raise Exception( + f"Can't encrypt object because the path {sensitive_field.path} doesn't exist." + ) + + modified_value = operation(field_value) + + dpath.util.set(report, sensitive_field.path, modified_value, sensitive_field.path_separator) diff --git a/monkey/monkey_island/cc/server_utils/encryption/string_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/string_encryptor.py new file mode 100644 index 000000000..64bde517c --- /dev/null +++ b/monkey/monkey_island/cc/server_utils/encryption/string_encryptor.py @@ -0,0 +1,9 @@ +from monkey_island.cc.server_utils.encryptor import get_encryptor + + +def encrypt(cleartext: str) -> str: + return get_encryptor().enc(cleartext) + + +def decrypt(cyphertext: str) -> str: + return get_encryptor().dec(cyphertext)