mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-03-22 03:08:23 +00:00
feat(guardduty): add org-wide delegated admin check across all regions (#9867)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
This commit is contained in:
@@ -9,6 +9,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
|||||||
- `entra_conditional_access_policy_approved_client_app_required_for_mobile` check for m365 provider [(#10216)](https://github.com/prowler-cloud/prowler/pull/10216)
|
- `entra_conditional_access_policy_approved_client_app_required_for_mobile` check for m365 provider [(#10216)](https://github.com/prowler-cloud/prowler/pull/10216)
|
||||||
- `entra_conditional_access_policy_compliant_device_hybrid_joined_device_mfa_required` check for M365 provider [(#10197)](https://github.com/prowler-cloud/prowler/pull/10197)
|
- `entra_conditional_access_policy_compliant_device_hybrid_joined_device_mfa_required` check for M365 provider [(#10197)](https://github.com/prowler-cloud/prowler/pull/10197)
|
||||||
- Add `trusted_ips` configurable option to `opensearch_service_domains_not_publicly_accessible` check to reduce false positives on IP-restricted policies [(#8631)](https://github.com/prowler-cloud/prowler/pull/8631)
|
- Add `trusted_ips` configurable option to `opensearch_service_domains_not_publicly_accessible` check to reduce false positives on IP-restricted policies [(#8631)](https://github.com/prowler-cloud/prowler/pull/8631)
|
||||||
|
- `guardduty_delegated_admin_enabled_all_regions` check for AWS provider [(#9867)](https://github.com/prowler-cloud/prowler/pull/9867)
|
||||||
|
|
||||||
### 🔄 Changed
|
### 🔄 Changed
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"Provider": "aws",
|
||||||
|
"CheckID": "guardduty_delegated_admin_enabled_all_regions",
|
||||||
|
"CheckTitle": "GuardDuty has delegated admin configured and is enabled in all regions with organization auto-enable",
|
||||||
|
"CheckType": [
|
||||||
|
"Software and Configuration Checks/AWS Security Best Practices",
|
||||||
|
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices"
|
||||||
|
],
|
||||||
|
"ServiceName": "guardduty",
|
||||||
|
"SubServiceName": "",
|
||||||
|
"ResourceIdTemplate": "",
|
||||||
|
"Severity": "high",
|
||||||
|
"ResourceType": "AwsGuardDutyDetector",
|
||||||
|
"ResourceGroup": "security",
|
||||||
|
"Description": "**Amazon GuardDuty** has a delegated administrator configured at the organization level, detectors are enabled in all opted-in regions, and organization auto-enable is active for new member accounts.",
|
||||||
|
"Risk": "Without org-wide **Amazon GuardDuty** configuration, gaps can occur where **GuardDuty** may be enabled in some regions but not others. Delegated admin may not be set consistently, and new accounts may not be automatically enrolled. This fragments **threat visibility**, delays **incident response**, and allows adversaries to exploit unmonitored regions or accounts for **lateral movement**, **persistence**, and **data exfiltration**.",
|
||||||
|
"RelatedUrl": "",
|
||||||
|
"AdditionalURLs": [
|
||||||
|
"https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_organizations.html",
|
||||||
|
"https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_multi-account.html",
|
||||||
|
"https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-guardduty.html"
|
||||||
|
],
|
||||||
|
"Remediation": {
|
||||||
|
"Code": {
|
||||||
|
"CLI": "aws guardduty enable-organization-admin-account --admin-account-id <ADMIN_ACCOUNT_ID> && aws guardduty update-organization-configuration --detector-id <DETECTOR_ID> --auto-enable-organization-members ALL",
|
||||||
|
"NativeIaC": "",
|
||||||
|
"Other": "1. Sign in to the AWS Organizations management account\n2. Open the AWS Organizations console\n3. Navigate to Services > Amazon GuardDuty\n4. Click Register delegated administrator and enter the security account ID\n5. Switch to the delegated admin account\n6. In GuardDuty console, go to Settings > Accounts\n7. Enable auto-enable for all organization members\n8. Repeat detector enablement for all opted-in regions",
|
||||||
|
"Terraform": ""
|
||||||
|
},
|
||||||
|
"Recommendation": {
|
||||||
|
"Text": "Configure a **delegated administrator** for GuardDuty via AWS Organizations. Enable GuardDuty detectors in **all opted-in regions** and configure **auto-enable** to automatically enroll new member accounts. This ensures consistent threat detection coverage across the entire organization.",
|
||||||
|
"Url": "https://hub.prowler.com/check/guardduty_delegated_admin_enabled_all_regions"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Categories": [
|
||||||
|
"forensics-ready"
|
||||||
|
],
|
||||||
|
"DependsOn": [],
|
||||||
|
"RelatedTo": [
|
||||||
|
"guardduty_is_enabled",
|
||||||
|
"guardduty_centrally_managed"
|
||||||
|
],
|
||||||
|
"Notes": "This check requires execution from the organization management account or delegated administrator account to access organization-level APIs."
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_client import guardduty_client
|
||||||
|
|
||||||
|
|
||||||
|
class guardduty_delegated_admin_enabled_all_regions(Check):
|
||||||
|
"""Ensure GuardDuty has a delegated admin and is enabled in all regions.
|
||||||
|
|
||||||
|
This check verifies that:
|
||||||
|
1. A delegated administrator account is configured for GuardDuty
|
||||||
|
2. GuardDuty detectors are enabled in each region
|
||||||
|
3. Organization auto-enable is configured for new member accounts
|
||||||
|
"""
|
||||||
|
|
||||||
|
def execute(self) -> list[Check_Report_AWS]:
|
||||||
|
"""Execute the check logic.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A list of reports containing the result of the check for each region.
|
||||||
|
"""
|
||||||
|
findings = []
|
||||||
|
|
||||||
|
# Build a set of regions that have an organization admin account configured
|
||||||
|
regions_with_admin = {
|
||||||
|
admin.region
|
||||||
|
for admin in guardduty_client.organization_admin_accounts
|
||||||
|
if admin.admin_status == "ENABLED"
|
||||||
|
}
|
||||||
|
|
||||||
|
for detector in guardduty_client.detectors:
|
||||||
|
report = Check_Report_AWS(metadata=self.metadata(), resource=detector)
|
||||||
|
|
||||||
|
# Check if this region has a delegated admin
|
||||||
|
has_delegated_admin = detector.region in regions_with_admin
|
||||||
|
|
||||||
|
# Check if detector is enabled
|
||||||
|
detector_enabled = detector.enabled_in_account and detector.status
|
||||||
|
|
||||||
|
# Check if auto-enable is configured for organization members
|
||||||
|
auto_enable_configured = detector.organization_auto_enable_members in (
|
||||||
|
"NEW",
|
||||||
|
"ALL",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Determine overall status
|
||||||
|
issues = []
|
||||||
|
if not has_delegated_admin:
|
||||||
|
issues.append("no delegated administrator configured")
|
||||||
|
if not detector_enabled:
|
||||||
|
issues.append("detector not enabled")
|
||||||
|
if not auto_enable_configured and detector.organization_config_available:
|
||||||
|
# Only report auto-enable issue if org config data is available
|
||||||
|
issues.append("organization auto-enable not configured")
|
||||||
|
|
||||||
|
if issues:
|
||||||
|
report.status = "FAIL"
|
||||||
|
report.status_extended = (
|
||||||
|
f"GuardDuty in region {detector.region} has issues: "
|
||||||
|
f"{', '.join(issues)}."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
report.status = "PASS"
|
||||||
|
report.status_extended = (
|
||||||
|
f"GuardDuty in region {detector.region} has delegated admin "
|
||||||
|
f"configured with detector enabled and organization auto-enable active."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Support muting non-default regions if configured
|
||||||
|
if report.status == "FAIL" and (
|
||||||
|
guardduty_client.audit_config.get("mute_non_default_regions", False)
|
||||||
|
and detector.region != guardduty_client.region
|
||||||
|
):
|
||||||
|
report.muted = True
|
||||||
|
|
||||||
|
findings.append(report)
|
||||||
|
|
||||||
|
return findings
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
from pydantic.v1 import BaseModel
|
from pydantic.v1 import BaseModel
|
||||||
|
|
||||||
from prowler.lib.logger import logger
|
from prowler.lib.logger import logger
|
||||||
@@ -12,12 +13,17 @@ class GuardDuty(AWSService):
|
|||||||
# Call AWSService's __init__
|
# Call AWSService's __init__
|
||||||
super().__init__(__class__.__name__, provider)
|
super().__init__(__class__.__name__, provider)
|
||||||
self.detectors = []
|
self.detectors = []
|
||||||
|
self.organization_admin_accounts = []
|
||||||
self.__threading_call__(self._list_detectors)
|
self.__threading_call__(self._list_detectors)
|
||||||
self.__threading_call__(self._get_detector, self.detectors)
|
self.__threading_call__(self._get_detector, self.detectors)
|
||||||
self._list_findings()
|
self._list_findings()
|
||||||
self._list_members()
|
self._list_members()
|
||||||
self._get_administrator_account()
|
self._get_administrator_account()
|
||||||
self._list_tags_for_resource()
|
self._list_tags_for_resource()
|
||||||
|
self.__threading_call__(self._list_organization_admin_accounts)
|
||||||
|
self.__threading_call__(
|
||||||
|
self._describe_organization_configuration, self.detectors
|
||||||
|
)
|
||||||
|
|
||||||
def _list_detectors(self, regional_client):
|
def _list_detectors(self, regional_client):
|
||||||
logger.info("GuardDuty - listing detectors...")
|
logger.info("GuardDuty - listing detectors...")
|
||||||
@@ -216,13 +222,97 @@ class GuardDuty(AWSService):
|
|||||||
f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}"
|
f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _list_organization_admin_accounts(self, regional_client):
|
||||||
|
"""List GuardDuty delegated administrator accounts for the organization.
|
||||||
|
|
||||||
|
This API is only available to the organization management account or
|
||||||
|
a delegated administrator account.
|
||||||
|
"""
|
||||||
|
logger.info("GuardDuty - listing organization admin accounts...")
|
||||||
|
try:
|
||||||
|
paginator = regional_client.get_paginator(
|
||||||
|
"list_organization_admin_accounts"
|
||||||
|
)
|
||||||
|
for page in paginator.paginate():
|
||||||
|
for admin in page.get("AdminAccounts", []):
|
||||||
|
admin_account = OrganizationAdminAccount(
|
||||||
|
admin_account_id=admin.get("AdminAccountId"),
|
||||||
|
admin_status=admin.get("AdminStatus"),
|
||||||
|
region=regional_client.region,
|
||||||
|
)
|
||||||
|
# Avoid duplicates across regions for the same admin account
|
||||||
|
if not any(
|
||||||
|
existing.admin_account_id == admin_account.admin_account_id
|
||||||
|
and existing.region == admin_account.region
|
||||||
|
for existing in self.organization_admin_accounts
|
||||||
|
):
|
||||||
|
self.organization_admin_accounts.append(admin_account)
|
||||||
|
except ClientError as error:
|
||||||
|
if error.response["Error"]["Code"] in (
|
||||||
|
"AccessDeniedException",
|
||||||
|
"BadRequestException",
|
||||||
|
):
|
||||||
|
logger.warning(
|
||||||
|
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.error(
|
||||||
|
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||||
|
)
|
||||||
|
except Exception as error:
|
||||||
|
logger.error(
|
||||||
|
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _describe_organization_configuration(self, detector):
|
||||||
|
"""Describe the organization configuration for a GuardDuty detector.
|
||||||
|
|
||||||
|
This provides information about auto-enable settings for the organization.
|
||||||
|
"""
|
||||||
|
logger.info("GuardDuty - describing organization configuration...")
|
||||||
|
try:
|
||||||
|
if detector.id and detector.enabled_in_account:
|
||||||
|
regional_client = self.regional_clients[detector.region]
|
||||||
|
org_config = regional_client.describe_organization_configuration(
|
||||||
|
DetectorId=detector.id
|
||||||
|
)
|
||||||
|
detector.organization_auto_enable_members = org_config.get(
|
||||||
|
"AutoEnableOrganizationMembers", "NONE"
|
||||||
|
)
|
||||||
|
detector.organization_config_available = True
|
||||||
|
except ClientError as error:
|
||||||
|
if error.response["Error"]["Code"] in (
|
||||||
|
"AccessDeniedException",
|
||||||
|
"BadRequestException",
|
||||||
|
):
|
||||||
|
# Expected when not running from management or delegated admin account
|
||||||
|
logger.warning(
|
||||||
|
f"{detector.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.error(
|
||||||
|
f"{detector.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||||
|
)
|
||||||
|
except Exception as error:
|
||||||
|
logger.error(
|
||||||
|
f"{detector.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizationAdminAccount(BaseModel):
|
||||||
|
"""Represents a GuardDuty delegated administrator account."""
|
||||||
|
|
||||||
|
admin_account_id: str
|
||||||
|
admin_status: str # ENABLED or DISABLE_IN_PROGRESS
|
||||||
|
region: str
|
||||||
|
|
||||||
|
|
||||||
class Detector(BaseModel):
|
class Detector(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
arn: str
|
arn: str
|
||||||
region: str
|
region: str
|
||||||
enabled_in_account: bool
|
enabled_in_account: bool
|
||||||
status: bool = None
|
status: Optional[bool] = None
|
||||||
findings: list = []
|
findings: list = []
|
||||||
member_accounts: list = []
|
member_accounts: list = []
|
||||||
administrator_account: str = None
|
administrator_account: str = None
|
||||||
@@ -233,3 +323,6 @@ class Detector(BaseModel):
|
|||||||
eks_runtime_monitoring: bool = False
|
eks_runtime_monitoring: bool = False
|
||||||
lambda_protection: bool = False
|
lambda_protection: bool = False
|
||||||
ec2_malware_protection: bool = False
|
ec2_malware_protection: bool = False
|
||||||
|
# Organization configuration fields
|
||||||
|
organization_auto_enable_members: str = "NONE" # NEW, ALL, or NONE
|
||||||
|
organization_config_available: bool = False
|
||||||
|
|||||||
@@ -0,0 +1,233 @@
|
|||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import botocore
|
||||||
|
from boto3 import client
|
||||||
|
from moto import mock_aws
|
||||||
|
|
||||||
|
from tests.providers.aws.utils import (
|
||||||
|
AWS_ACCOUNT_NUMBER,
|
||||||
|
AWS_REGION_EU_WEST_1,
|
||||||
|
set_mocked_aws_provider,
|
||||||
|
)
|
||||||
|
|
||||||
|
orig = botocore.client.BaseClient._make_api_call
|
||||||
|
|
||||||
|
|
||||||
|
def mock_make_api_call_org_admin_and_config(self, operation_name, api_params):
|
||||||
|
"""Mock organization admin accounts and configuration APIs."""
|
||||||
|
if operation_name == "ListOrganizationAdminAccounts":
|
||||||
|
return {
|
||||||
|
"AdminAccounts": [
|
||||||
|
{
|
||||||
|
"AdminAccountId": "123456789012",
|
||||||
|
"AdminStatus": "ENABLED",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if operation_name == "DescribeOrganizationConfiguration":
|
||||||
|
return {
|
||||||
|
"AutoEnableOrganizationMembers": "ALL",
|
||||||
|
}
|
||||||
|
return orig(self, operation_name, api_params)
|
||||||
|
|
||||||
|
|
||||||
|
def mock_make_api_call_org_admin_no_auto_enable(self, operation_name, api_params):
|
||||||
|
"""Mock organization admin configured but auto-enable disabled."""
|
||||||
|
if operation_name == "ListOrganizationAdminAccounts":
|
||||||
|
return {
|
||||||
|
"AdminAccounts": [
|
||||||
|
{
|
||||||
|
"AdminAccountId": "123456789012",
|
||||||
|
"AdminStatus": "ENABLED",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if operation_name == "DescribeOrganizationConfiguration":
|
||||||
|
return {
|
||||||
|
"AutoEnableOrganizationMembers": "NONE",
|
||||||
|
}
|
||||||
|
return orig(self, operation_name, api_params)
|
||||||
|
|
||||||
|
|
||||||
|
def mock_make_api_call_no_org_admin(self, operation_name, api_params):
|
||||||
|
"""Mock no organization admin configured."""
|
||||||
|
if operation_name == "ListOrganizationAdminAccounts":
|
||||||
|
return {"AdminAccounts": []}
|
||||||
|
if operation_name == "DescribeOrganizationConfiguration":
|
||||||
|
return {
|
||||||
|
"AutoEnableOrganizationMembers": "NONE",
|
||||||
|
}
|
||||||
|
return orig(self, operation_name, api_params)
|
||||||
|
|
||||||
|
|
||||||
|
class Test_guardduty_delegated_admin_enabled_all_regions:
|
||||||
|
@mock_aws
|
||||||
|
def test_no_detectors(self):
|
||||||
|
"""Test when no GuardDuty detectors exist."""
|
||||||
|
aws_provider = set_mocked_aws_provider()
|
||||||
|
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_service import GuardDuty
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||||
|
return_value=aws_provider,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions.guardduty_client",
|
||||||
|
new=GuardDuty(aws_provider),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions import (
|
||||||
|
guardduty_delegated_admin_enabled_all_regions,
|
||||||
|
)
|
||||||
|
|
||||||
|
check = guardduty_delegated_admin_enabled_all_regions()
|
||||||
|
result = check.execute()
|
||||||
|
|
||||||
|
# Should have findings for each region (with unknown detectors)
|
||||||
|
assert len(result) > 0
|
||||||
|
# All should fail since no detectors are enabled
|
||||||
|
for finding in result:
|
||||||
|
assert finding.status == "FAIL"
|
||||||
|
assert "detector not enabled" in finding.status_extended
|
||||||
|
|
||||||
|
@patch(
|
||||||
|
"botocore.client.BaseClient._make_api_call",
|
||||||
|
new=mock_make_api_call_no_org_admin,
|
||||||
|
)
|
||||||
|
@mock_aws
|
||||||
|
def test_detector_enabled_no_delegated_admin(self):
|
||||||
|
"""Test when detector is enabled but no delegated admin is configured."""
|
||||||
|
guardduty_client_boto = client("guardduty", region_name=AWS_REGION_EU_WEST_1)
|
||||||
|
detector_id = guardduty_client_boto.create_detector(Enable=True)["DetectorId"]
|
||||||
|
|
||||||
|
aws_provider = set_mocked_aws_provider()
|
||||||
|
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_service import GuardDuty
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||||
|
return_value=aws_provider,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions.guardduty_client",
|
||||||
|
new=GuardDuty(aws_provider),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions import (
|
||||||
|
guardduty_delegated_admin_enabled_all_regions,
|
||||||
|
)
|
||||||
|
|
||||||
|
check = guardduty_delegated_admin_enabled_all_regions()
|
||||||
|
result = check.execute()
|
||||||
|
|
||||||
|
# Find the result for our region
|
||||||
|
eu_west_1_result = None
|
||||||
|
for finding in result:
|
||||||
|
if finding.region == AWS_REGION_EU_WEST_1:
|
||||||
|
eu_west_1_result = finding
|
||||||
|
break
|
||||||
|
|
||||||
|
assert eu_west_1_result is not None
|
||||||
|
assert eu_west_1_result.status == "FAIL"
|
||||||
|
assert (
|
||||||
|
"no delegated administrator configured"
|
||||||
|
in eu_west_1_result.status_extended
|
||||||
|
)
|
||||||
|
assert eu_west_1_result.resource_id == detector_id
|
||||||
|
|
||||||
|
@patch(
|
||||||
|
"botocore.client.BaseClient._make_api_call",
|
||||||
|
new=mock_make_api_call_org_admin_no_auto_enable,
|
||||||
|
)
|
||||||
|
@mock_aws
|
||||||
|
def test_detector_enabled_with_admin_no_auto_enable(self):
|
||||||
|
"""Test when detector is enabled with delegated admin but auto-enable is off."""
|
||||||
|
guardduty_client_boto = client("guardduty", region_name=AWS_REGION_EU_WEST_1)
|
||||||
|
detector_id = guardduty_client_boto.create_detector(Enable=True)["DetectorId"]
|
||||||
|
|
||||||
|
aws_provider = set_mocked_aws_provider()
|
||||||
|
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_service import GuardDuty
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||||
|
return_value=aws_provider,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions.guardduty_client",
|
||||||
|
new=GuardDuty(aws_provider),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions import (
|
||||||
|
guardduty_delegated_admin_enabled_all_regions,
|
||||||
|
)
|
||||||
|
|
||||||
|
check = guardduty_delegated_admin_enabled_all_regions()
|
||||||
|
result = check.execute()
|
||||||
|
|
||||||
|
# Find the result for our region
|
||||||
|
eu_west_1_result = None
|
||||||
|
for finding in result:
|
||||||
|
if finding.region == AWS_REGION_EU_WEST_1:
|
||||||
|
eu_west_1_result = finding
|
||||||
|
break
|
||||||
|
|
||||||
|
assert eu_west_1_result is not None
|
||||||
|
assert eu_west_1_result.status == "FAIL"
|
||||||
|
assert (
|
||||||
|
"organization auto-enable not configured"
|
||||||
|
in eu_west_1_result.status_extended
|
||||||
|
)
|
||||||
|
assert eu_west_1_result.resource_id == detector_id
|
||||||
|
|
||||||
|
@patch(
|
||||||
|
"botocore.client.BaseClient._make_api_call",
|
||||||
|
new=mock_make_api_call_org_admin_and_config,
|
||||||
|
)
|
||||||
|
@mock_aws
|
||||||
|
def test_detector_enabled_with_admin_and_auto_enable(self):
|
||||||
|
"""Test when detector is enabled with delegated admin and auto-enable is on (PASS)."""
|
||||||
|
guardduty_client_boto = client("guardduty", region_name=AWS_REGION_EU_WEST_1)
|
||||||
|
detector_id = guardduty_client_boto.create_detector(Enable=True)["DetectorId"]
|
||||||
|
|
||||||
|
aws_provider = set_mocked_aws_provider()
|
||||||
|
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_service import GuardDuty
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||||
|
return_value=aws_provider,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions.guardduty_client",
|
||||||
|
new=GuardDuty(aws_provider),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
from prowler.providers.aws.services.guardduty.guardduty_delegated_admin_enabled_all_regions.guardduty_delegated_admin_enabled_all_regions import (
|
||||||
|
guardduty_delegated_admin_enabled_all_regions,
|
||||||
|
)
|
||||||
|
|
||||||
|
check = guardduty_delegated_admin_enabled_all_regions()
|
||||||
|
result = check.execute()
|
||||||
|
|
||||||
|
# Find the result for our region
|
||||||
|
eu_west_1_result = None
|
||||||
|
for finding in result:
|
||||||
|
if finding.region == AWS_REGION_EU_WEST_1:
|
||||||
|
eu_west_1_result = finding
|
||||||
|
break
|
||||||
|
|
||||||
|
assert eu_west_1_result is not None
|
||||||
|
assert eu_west_1_result.status == "PASS"
|
||||||
|
assert "delegated admin configured" in eu_west_1_result.status_extended
|
||||||
|
assert "auto-enable active" in eu_west_1_result.status_extended
|
||||||
|
assert eu_west_1_result.resource_id == detector_id
|
||||||
|
assert (
|
||||||
|
eu_west_1_result.resource_arn
|
||||||
|
== f"arn:aws:guardduty:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:detector/{detector_id}"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user