From a0a2d04efccf66529766f6aa47a731d83c8c16d4 Mon Sep 17 00:00:00 2001 From: Shrutika Kulkarni <73834811+kshrutik@users.noreply.github.com> Date: Tue, 29 Jun 2021 21:37:42 +0530 Subject: [PATCH] PLA-26195 - Handled PrincipalNotFound Exception in sql auditing job (#98) --- .../azure_sql_auditing_on_server.py | 60 ++++++++++++------- .../test_aws_s3_cloudtrail_public_access.py | 10 ++-- ..._key_vault_expiry_date_set_for_all_keys.py | 2 +- ...y_vault_expiry_date_set_for_all_secrets.py | 2 +- 4 files changed, 46 insertions(+), 28 deletions(-) diff --git a/remediation_worker/jobs/azure_sql_auditing_on_server/azure_sql_auditing_on_server.py b/remediation_worker/jobs/azure_sql_auditing_on_server/azure_sql_auditing_on_server.py index df05e04..2de4793 100644 --- a/remediation_worker/jobs/azure_sql_auditing_on_server/azure_sql_auditing_on_server.py +++ b/remediation_worker/jobs/azure_sql_auditing_on_server/azure_sql_auditing_on_server.py @@ -12,6 +12,7 @@ from azure.mgmt.monitor import MonitorClient from azure.identity import ClientSecretCredential from azure.graphrbac import GraphRbacManagementClient +from azure.core.exceptions import HttpResponseError from azure.mgmt.keyvault import KeyVaultManagementClient from azure.common.credentials import ServicePrincipalCredentials from azure.mgmt.authorization import AuthorizationManagementClient @@ -70,7 +71,6 @@ MAX_COUNT_REGION = 6 MAX_COUNT_COMPONENT = 4 - def generate_name(region, subscription_id, resource_group_name): """Generates a name for the resource :param region: location in which the resource exists @@ -741,16 +741,28 @@ def remediate( ) scope = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Storage/storageAccounts/{stg_account.name}" - # Assign Storage Blob Contributer role to the SQL Server - self.create_role_assignment( - stg_name, - subscription_id, - client_authorization, - guid, - scope, - principalId, - sql_server_name, + role_definition_id = f"/subscriptions/{subscription_id}/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe" + status = self.check_role_assignment( + client_authorization, scope, principalId, role_definition_id ) + try: + if status is False: + # Assign Storage Blob Contributer role to the SQL Server + self.create_role_assignment( + stg_name, + subscription_id, + client_authorization, + guid, + scope, + principalId, + sql_server_name, + ) + except HttpResponseError as e: + if e.status_code == 400: + logging.error(f"{str(e)}") + logging.info("In case of PrincipalNotFound error, retry remediating this finding after few minutes") + return -1 + else: # If the Storage Account Created by CHSS exists stg_id = stg_account.id @@ -763,17 +775,23 @@ def remediate( status = self.check_role_assignment( client_authorization, scope, principalId, role_definition_id ) - if status is False: - # If role assignment does not exists, assign the Storage Blob Contributer Role to the SQL Server - self.create_role_assignment( - stg_account.name, - subscription_id, - client_authorization, - guid, - scope, - principalId, - sql_server_name, - ) + try: + if status is False: + # If role assignment does not exists, assign the Storage Blob Contributer Role to the SQL Server + self.create_role_assignment( + stg_account.name, + subscription_id, + client_authorization, + guid, + scope, + principalId, + sql_server_name, + ) + except HttpResponseError as e: + if e.status_code == 400: + logging.error(f"{str(e)}") + logging.info("In case of PrincipalNotFound error, retry remediating this finding after few minutes") + return -1 else: logging.error("Resource group name not found") return -1 diff --git a/test/unit/test_aws_s3_cloudtrail_public_access.py b/test/unit/test_aws_s3_cloudtrail_public_access.py index c2b81df..3682a27 100644 --- a/test/unit/test_aws_s3_cloudtrail_public_access.py +++ b/test/unit/test_aws_s3_cloudtrail_public_access.py @@ -17,7 +17,7 @@ from botocore.exceptions import ClientError from remediation_worker.jobs.aws_s3_cloudtrail_public_access.aws_s3_cloudtrail_public_access import ( - CloudtrailS3RemovePublicAcces, + CloudtrailS3RemovePublicAccess, ) @@ -41,7 +41,7 @@ def valid_payload(): class TestCloudtrailS3PublicAccess(object): def test_parse_payload(self, valid_payload): - params = CloudtrailS3RemovePublicAcces().parse(valid_payload) + params = CloudtrailS3RemovePublicAccess().parse(valid_payload) assert params["region"] == "region" assert params["cloudtrail_name"] == "CloudTrail_name" assert params["cloud_account_id"] == "cloud_account_id" @@ -49,7 +49,7 @@ def test_parse_payload(self, valid_payload): def test_remediate_success_with_bucket_policy_public(self): client = Mock() cloudtrail_client = Mock() - action = CloudtrailS3RemovePublicAcces() + action = CloudtrailS3RemovePublicAccess() trail = { "Trail": { "Name": "CloudTrail_name", @@ -126,7 +126,7 @@ def test_remediate_success_with_bucket_policy_public(self): def test_remediate_success_without_bucket_policy_public(self): client = Mock() cloudtrail_client = Mock() - action = CloudtrailS3RemovePublicAcces() + action = CloudtrailS3RemovePublicAccess() trail = { "Trail": { "Name": "CloudTrail_name", @@ -188,6 +188,6 @@ def put_public_access_block(self, **kwargs): ) client = TestClient() - action = CloudtrailS3RemovePublicAcces() + action = CloudtrailS3RemovePublicAccess() with pytest.raises(Exception): assert action.remediate(client, "bucket_name", "cloud_account_id") diff --git a/test/unit/test_azure_key_vault_expiry_date_set_for_all_keys.py b/test/unit/test_azure_key_vault_expiry_date_set_for_all_keys.py index 0ea6c9e..938b7ec 100644 --- a/test/unit/test_azure_key_vault_expiry_date_set_for_all_keys.py +++ b/test/unit/test_azure_key_vault_expiry_date_set_for_all_keys.py @@ -29,7 +29,7 @@ def valid_payload(): "FindingInfo": { "FindingId": "d3bb1d9a-fe52-4458-9935-47183f140e6b", "ObjectId": "key_vault_name.key_name", - "ObjectChain": "{\\"cloudAccountId\\":\\"subscription_id\\",\\"entityId\\":\\"Azure.KeyVault.Key.d687b1a3-9b78-43b1-a17b-7de297fd1fce.integration-tests-postgresql-b3wx.Key.postgresqlwnuuobrlrwngs\\",\\"entityName\\":\\"key_vault_name.key_name\\",\\"entityType\\":\\"Azure.KeyVault.Key\\",\\"lastUpdateTime\\":\\"2020-09-09T00:36:35.000Z\\",\\"partitionKey\\":\\"d687b1a3-9b78-43b1-a17b-7de297fd1fce\\",\\"provider\\":\\"Azure\\",\\"region\\":\\"eastus\\",\\"service\\":\\"PostgreSQL\\", \\"properties\\":[{\\"name\\":\\"ResourceGroup\\",\\"stringV\\":\\"resource_group_name\\",\\"type\\":\\"string\\"}]}", + "ObjectChain": "{\\"cloudAccountId\\":\\"subscription_id\\",\\"entityId\\":\\"Azure.KeyVault.Key.d687b1a3-9b78-43b1-a17b-7de297fd1fce.integration-tests-postgresql-b3wx.Key.postgresqlwnuuobrlrwngs\\",\\"entityName\\":\\"key_vault_name.key_name\\",\\"entityType\\":\\"Azure.KeyVault.Key\\",\\"lastUpdateTime\\":\\"2020-09-09T00:36:35.000Z\\",\\"partitionKey\\":\\"d687b1a3-9b78-43b1-a17b-7de297fd1fce\\",\\"provider\\":\\"Azure\\",\\"region\\":\\"eastus\\",\\"service\\":\\"PostgreSQL\\", \\"properties\\":[{\\"name\\":\\"System:SourceEntityId\\",\\"stringV\\":\\"Azure.KeyVault.8aa70cc7-bf51-4e8c-baa0-368cb78b3c0c.resource_group_name.Vault.rem-testsjehb\\",\\"type\\":\\"string\\"}]}", "Region": "region" } } diff --git a/test/unit/test_azure_key_vault_expiry_date_set_for_all_secrets.py b/test/unit/test_azure_key_vault_expiry_date_set_for_all_secrets.py index c635dd4..5c88cf7 100644 --- a/test/unit/test_azure_key_vault_expiry_date_set_for_all_secrets.py +++ b/test/unit/test_azure_key_vault_expiry_date_set_for_all_secrets.py @@ -29,7 +29,7 @@ def valid_payload(): "FindingInfo": { "FindingId": "d3bb1d9a-fe52-4458-9935-47183f140e6b", "ObjectId": "key_vault_name.secret_name", - "ObjectChain": "{\\"cloudAccountId\\":\\"subscription_id\\",\\"entityId\\":\\"Azure.KeyVault.Secret.d687b1a3-9b78-43b1-a17b-7de297fd1fce.integration-tests-postgresql-b3wx.Key.postgresqlwnuuobrlrwngs\\",\\"entityName\\":\\"key_vault_name.key_name\\",\\"entityType\\":\\"Azure.KeyVault.Secret\\",\\"lastUpdateTime\\":\\"2020-09-09T00:36:35.000Z\\",\\"partitionKey\\":\\"d687b1a3-9b78-43b1-a17b-7de297fd1fce\\",\\"provider\\":\\"Azure\\",\\"region\\":\\"eastus\\",\\"service\\":\\"PostgreSQL\\", \\"properties\\":[{\\"name\\":\\"ResourceGroup\\",\\"stringV\\":\\"resource_group_name\\",\\"type\\":\\"string\\"}]}", + "ObjectChain": "{\\"cloudAccountId\\":\\"subscription_id\\",\\"entityId\\":\\"Azure.KeyVault.Secret.d687b1a3-9b78-43b1-a17b-7de297fd1fce.integration-tests-postgresql-b3wx.Key.postgresqlwnuuobrlrwngs\\",\\"entityName\\":\\"key_vault_name.key_name\\",\\"entityType\\":\\"Azure.KeyVault.Secret\\",\\"lastUpdateTime\\":\\"2020-09-09T00:36:35.000Z\\",\\"partitionKey\\":\\"d687b1a3-9b78-43b1-a17b-7de297fd1fce\\",\\"provider\\":\\"Azure\\",\\"region\\":\\"eastus\\",\\"service\\":\\"PostgreSQL\\", \\"properties\\":[{\\"name\\":\\"System:SourceEntityId\\",\\"stringV\\":\\"Azure.KeyVault.8aa70cc7-bf51-4e8c-baa0-368cb78b3c0c.resource_group_name.Vault.rem-testsjehb\\",\\"type\\":\\"string\\"}]}", "Region": "region" } }