From 0b4a341d2b4c71e71245f2dbace17d57bc136692 Mon Sep 17 00:00:00 2001 From: Max Maass Date: Fri, 13 Dec 2024 10:53:03 +0100 Subject: [PATCH] Adapt monitors to ignore disabled clients when demanded. Closes #46 --- .../protocol_mapper/protocol_mapper_with_config.py | 6 ++++++ .../service_account/service_account_with_group.py | 7 +++++++ .../service_account_with_sensitive_role.py | 10 ++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/kcwarden/monitors/protocol_mapper/protocol_mapper_with_config.py b/kcwarden/monitors/protocol_mapper/protocol_mapper_with_config.py index fe2a1c6..d36b5a6 100644 --- a/kcwarden/monitors/protocol_mapper/protocol_mapper_with_config.py +++ b/kcwarden/monitors/protocol_mapper/protocol_mapper_with_config.py @@ -71,6 +71,10 @@ def _generate_additional_details( helper.get_effective_roles_for_service_account(self._DB, saccount) ) return additional_details + + def _should_consider_client(self, client: Client) -> bool: + # Ignore clients that are disabled, if the global setting says so + return not self.is_ignored_disabled_client(client) def audit(self): custom_config = self.get_custom_config() @@ -87,6 +91,8 @@ def audit(self): for client in self._DB.get_all_clients(): if helper.matches_list_of_regexes(client.get_name(), allowed_clients): continue + if not self._should_consider_client(client): + continue # First, find all directly defined ProtocolMappers for mapper in client.get_protocol_mappers(): if self._protocol_mapper_matches_config(mapper, monitored_mapper_type, matched_config): diff --git a/kcwarden/monitors/service_account/service_account_with_group.py b/kcwarden/monitors/service_account/service_account_with_group.py index c8f7403..39bd145 100644 --- a/kcwarden/monitors/service_account/service_account_with_group.py +++ b/kcwarden/monitors/service_account/service_account_with_group.py @@ -1,5 +1,6 @@ from kcwarden.api import Monitor from kcwarden.custom_types.result import Severity +from kcwarden.custom_types.keycloak_object import ServiceAccount, Client from kcwarden.database import helper @@ -21,6 +22,10 @@ class ServiceAccountWithGroup(Monitor): HAS_CUSTOM_CONFIG = True CUSTOM_CONFIG_TEMPLATE = {"group": "/group path or regular expression", "allow_no_group": True} + def _should_consider_service_account(self, service_account: ServiceAccount): + client: Client = self._DB.get_client(service_account.get_client_id()) + return not self.is_ignored_disabled_client(client) + def audit(self): custom_config = self.get_custom_config() for monitor_definition in custom_config: @@ -34,6 +39,8 @@ def audit(self): continue for saccount in self._DB.get_all_service_accounts(): + if not self._should_consider_service_account(saccount): + continue assigned_groups = saccount.get_groups() if not allow_no_group and assigned_groups == []: diff --git a/kcwarden/monitors/service_account/service_account_with_sensitive_role.py b/kcwarden/monitors/service_account/service_account_with_sensitive_role.py index ef9e286..94f1c9b 100644 --- a/kcwarden/monitors/service_account/service_account_with_sensitive_role.py +++ b/kcwarden/monitors/service_account/service_account_with_sensitive_role.py @@ -1,5 +1,6 @@ from kcwarden.api import Monitor from kcwarden.custom_types.result import Severity +from kcwarden.custom_types.keycloak_object import Client, ServiceAccount from kcwarden.database import helper @@ -25,6 +26,11 @@ class ServiceAccountWithSensitiveRole(Monitor): "role-client": "Client name (set to 'realm' for realm roles). No regular expression support", } + def _should_consider_service_account(self, serviceaccount: ServiceAccount, allowed_service_accounts: list[str]) -> bool: + if not helper.matches_list_of_regexes(serviceaccount.get_name(), allowed_service_accounts): + client: Client = self._DB.get_client(serviceaccount.get_client_id()) + return not self.is_ignored_disabled_client(client) + def audit(self): custom_config = self.get_custom_config() for monitor_definition in custom_config: @@ -50,7 +56,7 @@ def audit(self): # Next, we need to find all service accounts that have at least one of these roles for considered_role in final_roles: for serviceaccount in helper.get_service_accounts_with_role(self._DB, considered_role): - if not helper.matches_list_of_regexes(serviceaccount.get_name(), allowed_service_accounts): + if self._should_consider_service_account(serviceaccount, allowed_service_accounts): yield self.generate_finding_with_severity_from_config( serviceaccount, monitor_definition, @@ -66,7 +72,7 @@ def audit(self): # And all service accounts that are in at least one of these groups for considered_group in groups: for serviceaccount in helper.get_service_accounts_in_group(self._DB, considered_group): - if not helper.matches_list_of_regexes(serviceaccount.get_name(), allowed_service_accounts): + if self._should_consider_service_account(serviceaccount, allowed_service_accounts): yield self.generate_finding_with_severity_from_config( serviceaccount, monitor_definition,