From e74f5fb9f3463b9a0af9eada20cf7335ceeaec6c Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:54:03 -0400 Subject: [PATCH] chore(backport): update v3 with latest changes (#4555) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Pepe Fagoaga Co-authored-by: Rubén De la Torre Vico --- .../providers/aws/aws_regions_by_service.json | 1 + .../organizations/organizations_service.py | 18 ++++-- .../providers/aws/services/s3/s3_service.py | 61 ++++++++----------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/prowler/providers/aws/aws_regions_by_service.json b/prowler/providers/aws/aws_regions_by_service.json index c4bb55202e..b213dacab2 100644 --- a/prowler/providers/aws/aws_regions_by_service.json +++ b/prowler/providers/aws/aws_regions_by_service.json @@ -4960,6 +4960,7 @@ "ap-southeast-3", "ap-southeast-4", "ca-central-1", + "ca-west-1", "eu-central-1", "eu-central-2", "eu-north-1", diff --git a/prowler/providers/aws/services/organizations/organizations_service.py b/prowler/providers/aws/services/organizations/organizations_service.py index fac7dfe89f..421afe9963 100644 --- a/prowler/providers/aws/services/organizations/organizations_service.py +++ b/prowler/providers/aws/services/organizations/organizations_service.py @@ -128,7 +128,7 @@ class Organizations(AWSService): finally: return self.policies - def __describe_policy__(self, policy_id): + def __describe_policy__(self, policy_id) -> dict: logger.info("Organizations - Describe policy: %s ...", policy_id) # This operation can be called only from the organization’s management account or by a member account that is a delegated administrator for an Amazon Web Services service. @@ -140,14 +140,18 @@ class Organizations(AWSService): .get("Policy", {}) .get("Content", "") ) + if isinstance(policy_content, str): + policy_content = json.loads(policy_content) + + return policy_content # This could be not be a dict, because json.loads could return a list or a string depending on the content of policy_content object. + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - finally: - return json.loads(policy_content) + return {} - def __list_targets_for_policy__(self, policy_id): + def __list_targets_for_policy__(self, policy_id) -> list: logger.info("Organizations - List Targets for policy: %s ...", policy_id) try: @@ -156,12 +160,14 @@ class Organizations(AWSService): targets_for_policy = self.client.list_targets_for_policy( PolicyId=policy_id )["Targets"] + + return targets_for_policy + except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - finally: - return targets_for_policy + return [] def __list_delegated_administrators__(self): logger.info("Organizations - List Delegated Administrators") diff --git a/prowler/providers/aws/services/s3/s3_service.py b/prowler/providers/aws/services/s3/s3_service.py index 4e47fa3090..99c03c4011 100644 --- a/prowler/providers/aws/services/s3/s3_service.py +++ b/prowler/providers/aws/services/s3/s3_service.py @@ -1,5 +1,4 @@ import json -import threading from typing import Optional from botocore.client import ClientError @@ -18,30 +17,15 @@ class S3(AWSService): self.account_arn_template = f"arn:{self.audited_partition}:s3:{self.region}:{self.audited_account}:account" self.regions_with_buckets = [] self.buckets = self.__list_buckets__(audit_info) - self.__threading_call__(self.__get_bucket_versioning__) - self.__threading_call__(self.__get_bucket_logging__) - self.__threading_call__(self.__get_bucket_policy__) - self.__threading_call__(self.__get_bucket_acl__) - self.__threading_call__(self.__get_public_access_block__) - self.__threading_call__(self.__get_bucket_encryption__) - self.__threading_call__(self.__get_bucket_ownership_controls__) - self.__threading_call__(self.__get_object_lock_configuration__) - self.__threading_call__(self.__get_bucket_tagging__) - - # In the S3 service we override the "__threading_call__" method because we spawn a process per bucket instead of per region - # TODO: Replace the above function with the service __threading_call__ using the buckets as the iterator - def __threading_call__(self, call): - threads = [] - for bucket in self.buckets: - if bucket.region in self.regional_clients: - regional_client = self.regional_clients[bucket.region] - threads.append( - threading.Thread(target=call, args=(bucket, regional_client)) - ) - for t in threads: - t.start() - for t in threads: - t.join() + self.__threading_call__(self.__get_bucket_versioning__, self.buckets) + self.__threading_call__(self.__get_bucket_logging__, self.buckets) + self.__threading_call__(self.__get_bucket_policy__, self.buckets) + self.__threading_call__(self.__get_bucket_acl__, self.buckets) + self.__threading_call__(self.__get_public_access_block__, self.buckets) + self.__threading_call__(self.__get_bucket_encryption__, self.buckets) + self.__threading_call__(self.__get_bucket_ownership_controls__, self.buckets) + self.__threading_call__(self.__get_object_lock_configuration__, self.buckets) + self.__threading_call__(self.__get_bucket_tagging__, self.buckets) def __list_buckets__(self, audit_info): logger.info("S3 - Listing buckets...") @@ -107,9 +91,10 @@ class S3(AWSService): ) return buckets - def __get_bucket_versioning__(self, bucket, regional_client): + def __get_bucket_versioning__(self, bucket): logger.info("S3 - Get buckets versioning...") try: + regional_client = self.regional_clients[bucket.region] bucket_versioning = regional_client.get_bucket_versioning( Bucket=bucket.name ) @@ -138,9 +123,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_bucket_encryption__(self, bucket, regional_client): + def __get_bucket_encryption__(self, bucket): logger.info("S3 - Get buckets encryption...") try: + regional_client = self.regional_clients[bucket.region] bucket.encryption = regional_client.get_bucket_encryption( Bucket=bucket.name )["ServerSideEncryptionConfiguration"]["Rules"][0][ @@ -169,9 +155,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_bucket_logging__(self, bucket, regional_client): + def __get_bucket_logging__(self, bucket): logger.info("S3 - Get buckets logging...") try: + regional_client = self.regional_clients[bucket.region] bucket_logging = regional_client.get_bucket_logging(Bucket=bucket.name) if "LoggingEnabled" in bucket_logging: bucket.logging = True @@ -197,9 +184,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_public_access_block__(self, bucket, regional_client): + def __get_public_access_block__(self, bucket): logger.info("S3 - Get buckets public access block...") try: + regional_client = self.regional_clients[bucket.region] public_access_block = regional_client.get_public_access_block( Bucket=bucket.name )["PublicAccessBlockConfiguration"] @@ -239,9 +227,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_bucket_acl__(self, bucket, regional_client): + def __get_bucket_acl__(self, bucket): logger.info("S3 - Get buckets acl...") try: + regional_client = self.regional_clients[bucket.region] grantees = [] acl_grants = regional_client.get_bucket_acl(Bucket=bucket.name)["Grants"] for grant in acl_grants: @@ -275,9 +264,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_bucket_policy__(self, bucket, regional_client): + def __get_bucket_policy__(self, bucket): logger.info("S3 - Get buckets policy...") try: + regional_client = self.regional_clients[bucket.region] bucket.policy = json.loads( regional_client.get_bucket_policy(Bucket=bucket.name)["Policy"] ) @@ -302,9 +292,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_bucket_ownership_controls__(self, bucket, regional_client): + def __get_bucket_ownership_controls__(self, bucket): logger.info("S3 - Get buckets ownership controls...") try: + regional_client = self.regional_clients[bucket.region] bucket.ownership = regional_client.get_bucket_ownership_controls( Bucket=bucket.name )["OwnershipControls"]["Rules"][0]["ObjectOwnership"] @@ -329,9 +320,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_object_lock_configuration__(self, bucket, regional_client): + def __get_object_lock_configuration__(self, bucket): logger.info("S3 - Get buckets ownership controls...") try: + regional_client = self.regional_clients[bucket.region] regional_client.get_object_lock_configuration(Bucket=bucket.name) bucket.object_lock = True except Exception as error: @@ -358,9 +350,10 @@ class S3(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def __get_bucket_tagging__(self, bucket, regional_client): + def __get_bucket_tagging__(self, bucket): logger.info("S3 - Get buckets logging...") try: + regional_client = self.regional_clients[bucket.region] bucket_tags = regional_client.get_bucket_tagging(Bucket=bucket.name)[ "TagSet" ]