-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use automatic importing for collecting built-in auditors and monitors.
Therefore, monitors are moved into separate packages per entity. Signed-off-by: Tim Walter <[email protected]>
- Loading branch information
Showing
24 changed files
with
273 additions
and
264 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from kcwarden.api import Monitor | ||
from kcwarden.custom_types.result import Severity | ||
from kcwarden.database import helper | ||
|
||
|
||
class ClientWithSensitiveScope(Monitor): | ||
"""Checks for the use of sensitive scopes. | ||
In some situations, specific scopes should only be available for specific clients. | ||
This Auditor checks which OIDC clients have a specific scope in their default or | ||
optional scopes. You can define which clients you would expect to have access to | ||
this scope in the config file. All other clients that have the scope are reported. | ||
If no scopes are defined in the config file, this auditor will not run. | ||
""" | ||
|
||
DEFAULT_SEVERITY = Severity.Medium | ||
SHORT_DESCRIPTION = "Unexpected client uses monitored sensitive scope" | ||
LONG_DESCRIPTION = "In the configuration, you have defined this scope to be sensitive, and defined a set of expected clients that are allowed to use it. An unexpected client has been detected that has been assigned this scope as either optional or default scope. If this is expected, please add it to the allowlist in the configuration file." | ||
REFERENCE = "" | ||
HAS_CUSTOM_CONFIG = True | ||
CUSTOM_CONFIG_TEMPLATE = { | ||
"scope": "scope name or regular expression", | ||
} | ||
|
||
def audit(self): | ||
custom_config = self.get_custom_config() | ||
for monitor_definition in custom_config: | ||
# Load config | ||
monitored_scope: str = monitor_definition["scope"] | ||
allowed_clients: list[str] = monitor_definition["allowed"] | ||
# Skip default config entry, in case it was still present | ||
if monitored_scope == self.CUSTOM_CONFIG_TEMPLATE["scope"]: # type: ignore - confused linter | ||
continue | ||
for client in self._DB.get_all_clients(): | ||
# if self.is_not_ignored(client) and (monitored_scope in client.get_default_client_scopes() or monitored_scope in client.get_optional_client_scopes()): | ||
if self.is_not_ignored(client) and ( | ||
helper.regex_matches_list_entry(monitored_scope, client.get_default_client_scopes()) | ||
or helper.regex_matches_list_entry(monitored_scope, client.get_optional_client_scopes()) | ||
): | ||
if not helper.matches_list_of_regexes(client.get_name(), allowed_clients): | ||
yield self.generate_finding_with_severity_from_config( | ||
client, | ||
monitor_definition, | ||
additional_details={ | ||
"monitored_scope": monitored_scope, | ||
"default_scopes": client.get_default_client_scopes(), | ||
"optional_scopes": client.get_optional_client_scopes(), | ||
}, | ||
) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
53 changes: 53 additions & 0 deletions
53
kcwarden/monitors/service_account/service_account_with_group.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from kcwarden.api import Monitor | ||
from kcwarden.custom_types.result import Severity | ||
from kcwarden.database import helper | ||
|
||
|
||
class ServiceAccountWithGroup(Monitor): | ||
"""Checks for service accounts assigned to specific groups. | ||
You may have a situation where you expect all service accounts to be assigned | ||
to specific groups (e.g., "/TecUser"), or no service accounts to be | ||
assigned to a group (e.g., "no service accounts should be assigned to /Customer"). | ||
This monitor allows you to check for any violations of these rules. | ||
If no groups are defined in the config file, this auditor will not run. | ||
""" | ||
|
||
DEFAULT_SEVERITY = Severity.Medium | ||
SHORT_DESCRIPTION = "Service Account in unexpected group" | ||
LONG_DESCRIPTION = "In the configuration, you have defined rules for which groups service accounts are allowed to be assigned to. This service account violates these rules. If this is a mistake, add an exclusion in the configuration." | ||
REFERENCE = "" | ||
HAS_CUSTOM_CONFIG = True | ||
CUSTOM_CONFIG_TEMPLATE = {"group": "/group path or regular expression", "allow_no_group": True} | ||
|
||
def audit(self): | ||
custom_config = self.get_custom_config() | ||
for monitor_definition in custom_config: | ||
# Load config | ||
monitored_group: str = monitor_definition["group"] | ||
allowed_service_accounts: list[str] = monitor_definition["allowed"] | ||
allow_no_group: bool = monitor_definition["allow_no_group"] | ||
|
||
# Skip default config entry, in case it was still present | ||
if monitored_group == self.CUSTOM_CONFIG_TEMPLATE["group"]: # type: ignore - confused linter | ||
continue | ||
|
||
for saccount in self._DB.get_all_service_accounts(): | ||
assigned_groups = saccount.get_groups() | ||
|
||
if not allow_no_group and assigned_groups == []: | ||
yield self.generate_finding_with_severity_from_config( | ||
saccount, | ||
monitor_definition, | ||
additional_details={"monitored_group": monitored_group, "assigned_groups": assigned_groups}, | ||
) | ||
continue | ||
|
||
if helper.regex_matches_list_entry(monitored_group, assigned_groups): | ||
if not helper.matches_list_of_regexes(saccount.get_username(), allowed_service_accounts): | ||
yield self.generate_finding_with_severity_from_config( | ||
saccount, | ||
monitor_definition, | ||
additional_details={"monitored_group": monitored_group, "assigned_groups": assigned_groups}, | ||
) |
Oops, something went wrong.