From fefdce129ba437f460bb23cb81a4473be55c0d08 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Date: Wed, 9 Apr 2025 10:34:38 -0400 Subject: [PATCH] fix: handle errors in AWS and Azure (#7482) --- api/src/backend/config/settings/sentry.py | 5 +++- .../cloudtrail_multi_region_enabled.py | 21 +++++++------- ...ompromised_credentials_sign_in_attempts.py | 1 + ...ks_potential_malicious_sign_in_attempts.py | 28 +++++++++++-------- ...rds_cluster_critical_event_subscription.py | 12 ++++++-- .../aws/services/redshift/redshift_service.py | 2 +- .../azure/services/network/network_service.py | 12 ++++++-- 7 files changed, 52 insertions(+), 29 deletions(-) diff --git a/api/src/backend/config/settings/sentry.py b/api/src/backend/config/settings/sentry.py index 89c77feba5..5aeda7a88a 100644 --- a/api/src/backend/config/settings/sentry.py +++ b/api/src/backend/config/settings/sentry.py @@ -12,6 +12,8 @@ IGNORED_EXCEPTIONS = [ "UnauthorizedOperation", "AuthFailure", "InvalidClientTokenId", + "AWSInvalidProviderIdError", + "InternalServerErrorException", "AccessDenied", "No Shodan API Key", # Shodan Check "RequestLimitExceeded", # For now we don't want to log the RequestLimitExceeded errors @@ -36,7 +38,7 @@ IGNORED_EXCEPTIONS = [ "InvalidRequestException", "RequestExpired", "ConnectionClosedError", - "HTTPSConnectionPool", + "MaxRetryError", "Pool is closed", # The following comes from urllib3: eu-west-1 -- HTTPClientError[126]: An HTTP Client raised an unhandled exception: AWSHTTPSConnectionPool(host='hostname.s3.eu-west-1.amazonaws.com', port=443): Pool is closed. # Authentication Errors from GCP "ClientAuthenticationError", @@ -55,6 +57,7 @@ IGNORED_EXCEPTIONS = [ "AzureNotValidClientIdError", "AzureNotValidClientSecretError", "AzureNotValidTenantIdError", + "AzureInvalidProviderIdError", "AzureTenantIdAndClientSecretNotBelongingToClientIdError", "AzureTenantIdAndClientIdNotBelongingToClientSecretError", "AzureClientIdAndClientSecretNotBelongingToTenantIdError", diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py index 0c8ca0439f..b4b7349fc4 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.py @@ -9,6 +9,7 @@ class cloudtrail_multi_region_enabled(Check): findings = [] if cloudtrail_client.trails is not None: for region in cloudtrail_client.regional_clients.keys(): + trail_is_logging = False for trail in cloudtrail_client.trails.values(): if trail.region == region or trail.is_multiregion: report = Check_Report_AWS( @@ -16,6 +17,7 @@ class cloudtrail_multi_region_enabled(Check): ) report.region = region if trail.is_logging: + trail_is_logging = True report.status = "PASS" if trail.is_multiregion: report.status_extended = f"Trail {trail.name} is multiregion and it is logging." @@ -25,16 +27,15 @@ class cloudtrail_multi_region_enabled(Check): # Store the finding and exit the loop findings.append(report) break - else: - report.status = "FAIL" - report.status_extended = ( - "No CloudTrail trails enabled with logging were found." - ) - report.resource_arn = ( - cloudtrail_client._get_trail_arn_template(region) - ) - report.resource_id = cloudtrail_client.audited_account # If there are no trails logging it is needed to store the FAIL once all the trails have been checked - if report.status == "FAIL": + if not trail_is_logging: + report.status = "FAIL" + report.status_extended = ( + "No CloudTrail trails enabled with logging were found." + ) + report.resource_arn = cloudtrail_client._get_trail_arn_template( + region + ) + report.resource_id = cloudtrail_client.audited_account findings.append(report) return findings diff --git a/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts.py b/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts.py index 0552c01c57..b0eee2b4b3 100644 --- a/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts.py +++ b/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts/cognito_user_pool_blocks_compromised_credentials_sign_in_attempts.py @@ -9,6 +9,7 @@ class cognito_user_pool_blocks_compromised_credentials_sign_in_attempts(Check): report = Check_Report_AWS(metadata=self.metadata(), resource=pool) if ( pool.advanced_security_mode == "ENFORCED" + and pool.risk_configuration and "SIGN_IN" in pool.risk_configuration.compromised_credentials_risk_configuration.event_filter and pool.risk_configuration.compromised_credentials_risk_configuration.actions diff --git a/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_potential_malicious_sign_in_attempts/cognito_user_pool_blocks_potential_malicious_sign_in_attempts.py b/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_potential_malicious_sign_in_attempts/cognito_user_pool_blocks_potential_malicious_sign_in_attempts.py index 6d0baeded4..6ed3f34d75 100644 --- a/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_potential_malicious_sign_in_attempts/cognito_user_pool_blocks_potential_malicious_sign_in_attempts.py +++ b/prowler/providers/aws/services/cognito/cognito_user_pool_blocks_potential_malicious_sign_in_attempts/cognito_user_pool_blocks_potential_malicious_sign_in_attempts.py @@ -7,18 +7,22 @@ class cognito_user_pool_blocks_potential_malicious_sign_in_attempts(Check): findings = [] for pool in cognito_idp_client.user_pools.values(): report = Check_Report_AWS(metadata=self.metadata(), resource=pool) - if pool.advanced_security_mode == "ENFORCED" and all( - [ - pool.risk_configuration.account_takeover_risk_configuration.low_action - and pool.risk_configuration.account_takeover_risk_configuration.low_action - == "BLOCK", - pool.risk_configuration.account_takeover_risk_configuration.medium_action - and pool.risk_configuration.account_takeover_risk_configuration.medium_action - == "BLOCK", - pool.risk_configuration.account_takeover_risk_configuration.high_action - and pool.risk_configuration.account_takeover_risk_configuration.high_action - == "BLOCK", - ] + if ( + pool.advanced_security_mode == "ENFORCED" + and pool.risk_configuration + and all( + [ + pool.risk_configuration.account_takeover_risk_configuration.low_action + and pool.risk_configuration.account_takeover_risk_configuration.low_action + == "BLOCK", + pool.risk_configuration.account_takeover_risk_configuration.medium_action + and pool.risk_configuration.account_takeover_risk_configuration.medium_action + == "BLOCK", + pool.risk_configuration.account_takeover_risk_configuration.high_action + and pool.risk_configuration.account_takeover_risk_configuration.high_action + == "BLOCK", + ] + ) ): report.status = "PASS" report.status_extended = f"User pool {pool.name} blocks all potential malicious sign-in attempts." diff --git a/prowler/providers/aws/services/rds/rds_cluster_critical_event_subscription/rds_cluster_critical_event_subscription.py b/prowler/providers/aws/services/rds/rds_cluster_critical_event_subscription/rds_cluster_critical_event_subscription.py index 336d2f3d80..4caff14289 100644 --- a/prowler/providers/aws/services/rds/rds_cluster_critical_event_subscription/rds_cluster_critical_event_subscription.py +++ b/prowler/providers/aws/services/rds/rds_cluster_critical_event_subscription/rds_cluster_critical_event_subscription.py @@ -13,23 +13,29 @@ class rds_cluster_critical_event_subscription(Check): report.resource_id = rds_client.audited_account report.resource_arn = rds_client._get_rds_arn_template(db_event.region) if db_event.source_type == "db-cluster" and db_event.enabled: - report = Check_Report_AWS( - metadata=self.metadata(), resource=db_event - ) if db_event.event_list == [] or set(db_event.event_list) == { "maintenance", "failure", }: + report = Check_Report_AWS( + metadata=self.metadata(), resource=db_event + ) report.status = "PASS" report.status_extended = "RDS cluster events are subscribed." elif db_event.event_list == ["maintenance"]: + report = Check_Report_AWS( + metadata=self.metadata(), resource=db_event + ) report.status = "FAIL" report.status_extended = ( "RDS cluster event category of failure is not subscribed." ) elif db_event.event_list == ["failure"]: + report = Check_Report_AWS( + metadata=self.metadata(), resource=db_event + ) report.status = "FAIL" report.status_extended = "RDS cluster event category of maintenance is not subscribed." diff --git a/prowler/providers/aws/services/redshift/redshift_service.py b/prowler/providers/aws/services/redshift/redshift_service.py index 8284b9d05d..b0f4a06421 100644 --- a/prowler/providers/aws/services/redshift/redshift_service.py +++ b/prowler/providers/aws/services/redshift/redshift_service.py @@ -124,7 +124,7 @@ class Redshift(AWSService): try: regional_client = self.regional_clients[cluster.region] cluster_parameter_groups = regional_client.describe_cluster_parameters( - ClusterParameterGroupName=cluster.parameter_group_name + ParameterGroupName=cluster.parameter_group_name ) for parameter_group in cluster_parameter_groups["Parameters"]: if parameter_group["ParameterName"].lower() == "require_ssl": diff --git a/prowler/providers/azure/services/network/network_service.py b/prowler/providers/azure/services/network/network_service.py index c6464133da..fb0e6f90ba 100644 --- a/prowler/providers/azure/services/network/network_service.py +++ b/prowler/providers/azure/services/network/network_service.py @@ -78,8 +78,16 @@ class Network(AzureService): FlowLog( id=flow_log.id, name=flow_log.name, - enabled=flow_log.properties.enabled, - retention_policy=flow_log.properties.retentionPolicy, + enabled=getattr( + getattr(flow_log, "properties", None), + "enabled", + False, + ), + retention_policy=getattr( + getattr(flow_log, "properties", None), + "retentionPolicy", + None, + ), ) for flow_log in flow_logs ],