mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-31 07:44:21 +00:00
Merge branch 'master' into PROWLER-1391-provider-contract-dynamic-discovery
This commit is contained in:
1373 files changed
+77907
-33050
No files matched your search
@@ -75,6 +75,7 @@ config_aws = {
|
||||
"mute_non_default_regions": False,
|
||||
"max_unused_access_keys_days": 45,
|
||||
"max_console_access_days": 45,
|
||||
"max_unused_sagemaker_access_days": 90,
|
||||
"shodan_api_key": None,
|
||||
"max_security_group_rules": 50,
|
||||
"max_ec2_instance_age_in_days": 180,
|
||||
|
||||
@@ -20,6 +20,8 @@ aws:
|
||||
max_unused_access_keys_days: 45
|
||||
# aws.iam_user_console_access_unused --> CIS recommends 45 days
|
||||
max_console_access_days: 45
|
||||
# aws.iam_user_access_not_stale_to_sagemaker --> default 90 days
|
||||
max_unused_sagemaker_access_days: 90
|
||||
|
||||
# AWS EC2 Configuration
|
||||
# aws.ec2_elastic_ip_shodan
|
||||
@@ -486,3 +488,11 @@ m365:
|
||||
# Exchange Mailbox Settings
|
||||
# m365.exchange_mailbox_properties_auditing_enabled
|
||||
audit_log_age: 90 # maximum number of days to keep audit logs
|
||||
|
||||
okta:
|
||||
# Okta Sign-On Policies
|
||||
# okta.signon_global_session_idle_timeout_15min
|
||||
okta_max_session_idle_minutes: 15
|
||||
# Okta Applications
|
||||
# okta.application_admin_console_session_idle_timeout_15min
|
||||
okta_admin_console_idle_timeout_max_minutes: 15
|
||||
@@ -1149,6 +1149,40 @@ class TestCheck:
|
||||
)
|
||||
assert findings[0].muted is True
|
||||
|
||||
def test_execute_azure_mutelist_passes_subscription_id_and_name(self):
|
||||
"""Test that execute() passes Azure subscription ID and display name."""
|
||||
subscription_id = "12345678-1234-1234-1234-123456789012"
|
||||
subscription_name = "subscription_1"
|
||||
|
||||
finding = Mock()
|
||||
finding.status = "PASS"
|
||||
finding.muted = False
|
||||
finding.subscription = subscription_id
|
||||
|
||||
check = Mock()
|
||||
check.CheckID = "azure_test_check"
|
||||
check.execute = Mock(return_value=[finding])
|
||||
|
||||
provider = mock.MagicMock()
|
||||
provider.type = "azure"
|
||||
provider.identity.subscriptions = {subscription_id: subscription_name}
|
||||
provider.mutelist.mutelist = {"Accounts": {subscription_name: {}}}
|
||||
provider.mutelist.is_finding_muted = Mock(return_value=True)
|
||||
|
||||
findings = execute(
|
||||
check=check,
|
||||
global_provider=provider,
|
||||
custom_checks_metadata=None,
|
||||
output_options=None,
|
||||
)
|
||||
|
||||
provider.mutelist.is_finding_muted.assert_called_once_with(
|
||||
subscription_id=subscription_id,
|
||||
subscription_name=subscription_name,
|
||||
finding=finding,
|
||||
)
|
||||
assert findings[0].muted is True
|
||||
|
||||
def test_execute_check_exception_only_logs(self, caplog):
|
||||
caplog.set_level(ERROR)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ prowler_command = "prowler"
|
||||
|
||||
# capsys
|
||||
# https://docs.pytest.org/en/7.1.x/how-to/capture-stdout-stderr.html
|
||||
prowler_default_usage_error = "usage: prowler [-h] [--version] {aws,azure,gcp,kubernetes,m365,github,googleworkspace,nhn,mongodbatlas,oraclecloud,alibabacloud,cloudflare,openstack,vercel,dashboard,iac,image,llm} ..."
|
||||
prowler_default_usage_error = "usage: prowler [-h] [--version] {aws,azure,gcp,kubernetes,m365,github,googleworkspace,okta,nhn,mongodbatlas,oraclecloud,alibabacloud,cloudflare,openstack,scaleway,vercel,dashboard,iac,image,llm} ..."
|
||||
|
||||
|
||||
def mock_get_available_providers():
|
||||
|
||||
File renamed without changes.
+17
-17
@@ -4,13 +4,13 @@ from unittest import mock
|
||||
from freezegun import freeze_time
|
||||
from mock import patch
|
||||
|
||||
from prowler.lib.outputs.compliance.essential_eight.essential_eight_aws import (
|
||||
EssentialEightAWS,
|
||||
from prowler.lib.outputs.compliance.asd_essential_eight.asd_essential_eight_aws import (
|
||||
ASDEssentialEightAWS,
|
||||
)
|
||||
from prowler.lib.outputs.compliance.essential_eight.models import (
|
||||
EssentialEightAWSModel,
|
||||
from prowler.lib.outputs.compliance.asd_essential_eight.models import (
|
||||
ASDEssentialEightAWSModel,
|
||||
)
|
||||
from tests.lib.outputs.compliance.fixtures import ESSENTIAL_EIGHT_AWS
|
||||
from tests.lib.outputs.compliance.fixtures import ASD_ESSENTIAL_EIGHT_AWS
|
||||
from tests.lib.outputs.fixtures.fixtures import generate_finding_output
|
||||
from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_EU_WEST_1
|
||||
|
||||
@@ -18,26 +18,26 @@ from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_EU_WEST_1
|
||||
# clause 8: removal of unsupported online services). The second Requirement is
|
||||
# E8-6.1 (Restrict Office macros, clause 1) which has no Checks and is therefore
|
||||
# emitted as a manual row.
|
||||
COMPLIANCE_NAME = "Essential-Eight-Nov 2023"
|
||||
COMPLIANCE_NAME = "ASD-Essential-Eight-Nov 2023"
|
||||
|
||||
|
||||
class TestEssentialEightAWS:
|
||||
class TestASDEssentialEightAWS:
|
||||
def test_output_transform(self):
|
||||
findings = [generate_finding_output(compliance={COMPLIANCE_NAME: "E8-1.8"})]
|
||||
|
||||
output = EssentialEightAWS(findings, ESSENTIAL_EIGHT_AWS)
|
||||
output = ASDEssentialEightAWS(findings, ASD_ESSENTIAL_EIGHT_AWS)
|
||||
output_data = output.data[0]
|
||||
assert isinstance(output_data, EssentialEightAWSModel)
|
||||
assert isinstance(output_data, ASDEssentialEightAWSModel)
|
||||
assert output_data.Provider == "aws"
|
||||
assert output_data.Framework == ESSENTIAL_EIGHT_AWS.Framework
|
||||
assert output_data.Name == ESSENTIAL_EIGHT_AWS.Name
|
||||
assert output_data.Description == ESSENTIAL_EIGHT_AWS.Description
|
||||
assert output_data.Framework == ASD_ESSENTIAL_EIGHT_AWS.Framework
|
||||
assert output_data.Name == ASD_ESSENTIAL_EIGHT_AWS.Name
|
||||
assert output_data.Description == ASD_ESSENTIAL_EIGHT_AWS.Description
|
||||
assert output_data.AccountId == AWS_ACCOUNT_NUMBER
|
||||
assert output_data.Region == AWS_REGION_EU_WEST_1
|
||||
assert output_data.Requirements_Id == "E8-1.8"
|
||||
assert (
|
||||
output_data.Requirements_Description
|
||||
== ESSENTIAL_EIGHT_AWS.Requirements[0].Description
|
||||
== ASD_ESSENTIAL_EIGHT_AWS.Requirements[0].Description
|
||||
)
|
||||
assert output_data.Requirements_Attributes_Section == "1 Patch applications"
|
||||
assert output_data.Requirements_Attributes_MaturityLevel == "ML1"
|
||||
@@ -49,7 +49,7 @@ class TestEssentialEightAWS:
|
||||
)
|
||||
assert (
|
||||
output_data.Requirements_Attributes_Description
|
||||
== ESSENTIAL_EIGHT_AWS.Requirements[0].Attributes[0].Description
|
||||
== ASD_ESSENTIAL_EIGHT_AWS.Requirements[0].Attributes[0].Description
|
||||
)
|
||||
assert output_data.Status == "PASS"
|
||||
assert output_data.StatusExtended == ""
|
||||
@@ -60,7 +60,7 @@ class TestEssentialEightAWS:
|
||||
|
||||
def test_manual_requirement(self):
|
||||
findings = [generate_finding_output(compliance={COMPLIANCE_NAME: "E8-1.8"})]
|
||||
output = EssentialEightAWS(findings, ESSENTIAL_EIGHT_AWS)
|
||||
output = ASDEssentialEightAWS(findings, ASD_ESSENTIAL_EIGHT_AWS)
|
||||
|
||||
# E8-6.1 (macros) has no Checks -> emitted as a manual row, non-applicable
|
||||
manual_rows = [row for row in output.data if row.Status == "MANUAL"]
|
||||
@@ -90,13 +90,13 @@ class TestEssentialEightAWS:
|
||||
|
||||
@freeze_time("2025-01-01 00:00:00")
|
||||
@mock.patch(
|
||||
"prowler.lib.outputs.compliance.essential_eight.essential_eight_aws.timestamp",
|
||||
"prowler.lib.outputs.compliance.asd_essential_eight.asd_essential_eight_aws.timestamp",
|
||||
"2025-01-01 00:00:00",
|
||||
)
|
||||
def test_batch_write_data_to_file(self):
|
||||
mock_file = StringIO()
|
||||
findings = [generate_finding_output(compliance={COMPLIANCE_NAME: "E8-1.8"})]
|
||||
output = EssentialEightAWS(findings, ESSENTIAL_EIGHT_AWS)
|
||||
output = ASDEssentialEightAWS(findings, ASD_ESSENTIAL_EIGHT_AWS)
|
||||
output._file_descriptor = mock_file
|
||||
|
||||
with patch.object(mock_file, "close", return_value=None):
|
||||
@@ -1,4 +1,5 @@
|
||||
from prowler.lib.check.compliance_models import (
|
||||
ASDEssentialEight_Requirement_Attribute,
|
||||
AWS_Well_Architected_Requirement_Attribute,
|
||||
CCC_Requirement_Attribute,
|
||||
CIS_Requirement_Attribute,
|
||||
@@ -7,7 +8,6 @@ from prowler.lib.check.compliance_models import (
|
||||
ENS_Requirement_Attribute,
|
||||
ENS_Requirement_Attribute_Nivel,
|
||||
ENS_Requirement_Attribute_Tipos,
|
||||
EssentialEight_Requirement_Attribute,
|
||||
Generic_Compliance_Requirement_Attribute,
|
||||
ISO27001_2013_Requirement_Attribute,
|
||||
KISA_ISMSP_Requirement_Attribute,
|
||||
@@ -128,7 +128,7 @@ CIS_2_0_GCP = Compliance(
|
||||
Description="This CIS Benchmark is the product of a community consensus process and consists of secure configuration guidelines developed for Google Cloud Computing Platform",
|
||||
Requirements=[
|
||||
Compliance_Requirement(
|
||||
Checks=["apikeys_key_exits"],
|
||||
Checks=["apikeys_key_exits", "service_test_check_id"],
|
||||
Id="2.13",
|
||||
Description="Ensure That Microsoft Defender for Databases Is Set To 'On'",
|
||||
Attributes=[
|
||||
@@ -177,7 +177,7 @@ CIS_1_8_KUBERNETES = Compliance(
|
||||
Description="This CIS Kubernetes Benchmark provides prescriptive guidance for establishing a secure configuration posture for Kubernetes v1.27.",
|
||||
Requirements=[
|
||||
Compliance_Requirement(
|
||||
Checks=["apiserver_always_pull_images_plugin"],
|
||||
Checks=["apiserver_always_pull_images_plugin", "service_test_check_id"],
|
||||
Id="1.1.3",
|
||||
Description="Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive",
|
||||
Attributes=[
|
||||
@@ -259,6 +259,7 @@ CIS_4_0_M365 = Compliance(
|
||||
Compliance_Requirement(
|
||||
Checks=[
|
||||
"mfa_delete_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
Id="2.1.3",
|
||||
Description="Ensure MFA Delete is enabled on S3 buckets",
|
||||
@@ -336,6 +337,7 @@ MITRE_ATTACK_AWS = Compliance(
|
||||
"inspector2_active_findings_exist",
|
||||
"awslambda_function_not_publicly_accessible",
|
||||
"ec2_instance_public_ip",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Mitre_Requirement(
|
||||
@@ -412,6 +414,7 @@ MITRE_ATTACK_AZURE = Compliance(
|
||||
"defender_ensure_notify_emails_to_owners",
|
||||
"defender_ensure_system_updates_are_applied",
|
||||
"defender_ensure_wdatp_is_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Mitre_Requirement(
|
||||
@@ -467,6 +470,7 @@ MITRE_ATTACK_GCP = Compliance(
|
||||
"compute_instance_public_ip",
|
||||
"compute_public_address_shodan",
|
||||
"kms_key_not_publicly_accessible",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Mitre_Requirement(
|
||||
@@ -514,7 +518,7 @@ ENS_RD2022_AWS = Compliance(
|
||||
Dependencias=[],
|
||||
)
|
||||
],
|
||||
Checks=["cloudtrail_log_file_validation_enabled"],
|
||||
Checks=["cloudtrail_log_file_validation_enabled", "service_test_check_id"],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
Id="op.exp.8.aws.ct.4",
|
||||
@@ -562,7 +566,7 @@ ENS_RD2022_AZURE = Compliance(
|
||||
Dependencias=[],
|
||||
)
|
||||
],
|
||||
Checks=["cloudtrail_log_file_validation_enabled"],
|
||||
Checks=["cloudtrail_log_file_validation_enabled", "service_test_check_id"],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
Id="op.exp.8.azure.ct.4",
|
||||
@@ -609,7 +613,7 @@ ENS_RD2022_GCP = Compliance(
|
||||
Dependencias=[],
|
||||
)
|
||||
],
|
||||
Checks=["cloudtrail_log_file_validation_enabled"],
|
||||
Checks=["cloudtrail_log_file_validation_enabled", "service_test_check_id"],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
Id="op.exp.8.gcp.ct.4",
|
||||
@@ -666,7 +670,10 @@ AWS_WELL_ARCHITECTED = Compliance(
|
||||
ImplementationGuidanceUrl="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_multi_accounts.html#implementation-guidance.",
|
||||
)
|
||||
],
|
||||
Checks=["organizations_account_part_of_organizations"],
|
||||
Checks=[
|
||||
"organizations_account_part_of_organizations",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
Id="SEC01-BP02",
|
||||
@@ -709,7 +716,7 @@ ISO27001_2013_AWS = Compliance(
|
||||
Check_Summary="Setup Encryption at rest for RDS instances",
|
||||
)
|
||||
],
|
||||
Checks=["rds_instance_storage_encrypted"],
|
||||
Checks=["rds_instance_storage_encrypted", "service_test_check_id"],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
Id="A.10.2",
|
||||
@@ -759,6 +766,7 @@ NIST_800_53_REVISION_4_AWS = Compliance(
|
||||
"rds_instance_integration_cloudwatch_logs",
|
||||
"redshift_cluster_audit_logging",
|
||||
"securityhub_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
@@ -815,6 +823,7 @@ KISA_ISMSP_AWS = Compliance(
|
||||
Checks=[
|
||||
"cloudwatch_log_metric_filter_authentication_failures",
|
||||
"cognito_user_pool_mfa_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
@@ -872,6 +881,7 @@ PROWLER_THREATSCORE_AWS = Compliance(
|
||||
],
|
||||
Checks=[
|
||||
"iam_root_mfa_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
@@ -916,6 +926,7 @@ PROWLER_THREATSCORE_AZURE = Compliance(
|
||||
],
|
||||
Checks=[
|
||||
"iam_root_mfa_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
@@ -960,6 +971,7 @@ PROWLER_THREATSCORE_GCP = Compliance(
|
||||
],
|
||||
Checks=[
|
||||
"iam_root_mfa_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
@@ -1004,6 +1016,7 @@ PROWLER_THREATSCORE_M365 = Compliance(
|
||||
],
|
||||
Checks=[
|
||||
"iam_root_mfa_enabled",
|
||||
"service_test_check_id",
|
||||
],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
@@ -1191,8 +1204,8 @@ CCC_GCP_FIXTURE = Compliance(
|
||||
],
|
||||
)
|
||||
|
||||
ESSENTIAL_EIGHT_AWS = Compliance(
|
||||
Framework="Essential-Eight",
|
||||
ASD_ESSENTIAL_EIGHT_AWS = Compliance(
|
||||
Framework="ASD-Essential-Eight",
|
||||
Name="ASD Essential Eight Maturity Model - Maturity Level One (AWS)",
|
||||
Version="Nov 2023",
|
||||
Provider="AWS",
|
||||
@@ -1202,7 +1215,7 @@ ESSENTIAL_EIGHT_AWS = Compliance(
|
||||
Id="E8-1.8",
|
||||
Description="Online services that are no longer supported by vendors are removed.",
|
||||
Attributes=[
|
||||
EssentialEight_Requirement_Attribute(
|
||||
ASDEssentialEight_Requirement_Attribute(
|
||||
Section="1 Patch applications",
|
||||
MaturityLevel="ML1",
|
||||
AssessmentStatus="Automated",
|
||||
@@ -1226,7 +1239,7 @@ ESSENTIAL_EIGHT_AWS = Compliance(
|
||||
Id="E8-6.1",
|
||||
Description="Microsoft Office macros are disabled for users that do not have a demonstrated business requirement.",
|
||||
Attributes=[
|
||||
EssentialEight_Requirement_Attribute(
|
||||
ASDEssentialEight_Requirement_Attribute(
|
||||
Section="6 Restrict Microsoft Office macros",
|
||||
MaturityLevel="ML1",
|
||||
AssessmentStatus="Manual",
|
||||
|
||||
@@ -5,6 +5,11 @@ from unittest import mock
|
||||
from freezegun import freeze_time
|
||||
from mock import patch
|
||||
|
||||
from prowler.lib.check.compliance_models import (
|
||||
Compliance,
|
||||
Compliance_Requirement,
|
||||
Generic_Compliance_Requirement_Attribute,
|
||||
)
|
||||
from prowler.lib.outputs.compliance.generic.generic import GenericCompliance
|
||||
from prowler.lib.outputs.compliance.generic.models import GenericComplianceModel
|
||||
from tests.lib.outputs.compliance.fixtures import NIST_800_53_REVISION_4_AWS
|
||||
@@ -129,3 +134,67 @@ class TestAWSGenericCompliance:
|
||||
expected_csv = f"PROVIDER;DESCRIPTION;ACCOUNTID;REGION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_SUBSECTION;REQUIREMENTS_ATTRIBUTES_SUBGROUP;REQUIREMENTS_ATTRIBUTES_SERVICE;REQUIREMENTS_ATTRIBUTES_TYPE;STATUS;STATUSEXTENDED;RESOURCEID;CHECKID;MUTED;RESOURCENAME;FRAMEWORK;NAME;REQUIREMENTS_ATTRIBUTES_COMMENT\r\naws;NIST 800-53 is a regulatory standard that defines the minimum baseline of security controls for all U.S. federal information systems except those related to national security. The controls defined in this standard are customizable and address a diverse set of security and privacy requirements.;123456789012;eu-west-1;{datetime.now()};ac_2_4;Account Management;Access Control (AC);Account Management (AC-2);;aws;;PASS;;;service_test_check_id;False;;NIST-800-53-Revision-4;National Institute of Standards and Technology (NIST) 800-53 Revision 4;\r\naws;NIST 800-53 is a regulatory standard that defines the minimum baseline of security controls for all U.S. federal information systems except those related to national security. The controls defined in this standard are customizable and address a diverse set of security and privacy requirements.;;;{datetime.now()};ac_2_5;Account Management;Access Control (AC);Account Management (AC-2);;aws;;MANUAL;Manual check;manual_check;manual;False;Manual check;NIST-800-53-Revision-4;National Institute of Standards and Technology (NIST) 800-53 Revision 4;\r\n"
|
||||
|
||||
assert content == expected_csv
|
||||
|
||||
def test_csv_row_count_matches_framework_checks_not_stored_compliance(self):
|
||||
"""Regression test for PROWLER-1763.
|
||||
|
||||
Ensures CSV emission is driven by the framework JSON's Requirements[].Checks
|
||||
(the same source the UI uses) and not by the per-finding `finding.compliance`
|
||||
snapshot stored at scan time. If `finding.check_id` is in a requirement's
|
||||
Checks list, the row must be emitted regardless of what was stored in
|
||||
`finding.compliance`. Conversely, a stale `finding.compliance` entry pointing
|
||||
to a requirement whose Checks list no longer contains the finding's check_id
|
||||
must not produce a row.
|
||||
"""
|
||||
framework_name = "Test-Framework-1763"
|
||||
compliance = Compliance(
|
||||
Framework=framework_name,
|
||||
Name=framework_name,
|
||||
Provider="AWS",
|
||||
Version="",
|
||||
Description="Regression fixture for PROWLER-1763",
|
||||
Requirements=[
|
||||
Compliance_Requirement(
|
||||
Id="req_in_framework",
|
||||
Description="Requirement currently in framework",
|
||||
Attributes=[
|
||||
Generic_Compliance_Requirement_Attribute(
|
||||
Section="Section A", Service="aws"
|
||||
)
|
||||
],
|
||||
Checks=["service_check_in_framework"],
|
||||
),
|
||||
Compliance_Requirement(
|
||||
Id="req_no_longer_in_framework",
|
||||
Description="Requirement whose Checks list no longer includes the finding's check_id",
|
||||
Attributes=[
|
||||
Generic_Compliance_Requirement_Attribute(
|
||||
Section="Section B", Service="aws"
|
||||
)
|
||||
],
|
||||
Checks=["service_different_check"],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
# Snapshot drift case: finding.compliance maps to a requirement whose
|
||||
# current Checks list no longer includes the finding's check_id, AND
|
||||
# the finding belongs to a requirement that is NOT in the snapshot.
|
||||
findings = [
|
||||
generate_finding_output(
|
||||
check_id="service_check_in_framework",
|
||||
compliance={framework_name: ["req_no_longer_in_framework"]},
|
||||
)
|
||||
]
|
||||
|
||||
output = GenericCompliance(findings, compliance)
|
||||
rows = [
|
||||
row
|
||||
for row in output.data
|
||||
if row.Status != "MANUAL" and row.ResourceName != "Manual check"
|
||||
]
|
||||
assert (
|
||||
len(rows) == 1
|
||||
), f"Expected 1 row driven by framework JSON, got {len(rows)}"
|
||||
assert rows[0].Requirements_Id == "req_in_framework"
|
||||
assert rows[0].CheckId == "service_check_in_framework"
|
||||
@@ -331,8 +331,8 @@ class TestFinding:
|
||||
assert finding_output.auth_method == "mock_identity_type: mock_identity_id"
|
||||
assert finding_output.account_organization_uid == "mock_tenant_id_1"
|
||||
assert finding_output.account_organization_name == "mock_tenant_domain"
|
||||
assert finding_output.account_uid == "mock_subscription_name"
|
||||
assert finding_output.account_name == "mock_subscription_id"
|
||||
assert finding_output.account_uid == "mock_subscription_id"
|
||||
assert finding_output.account_name == "mock_subscription_name"
|
||||
assert finding_output.resource_name == "test_resource_name"
|
||||
assert finding_output.resource_uid == "test_resource_id"
|
||||
assert finding_output.region == "us-west-1"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
from prowler.lib.outputs.summary_table import display_summary_table
|
||||
|
||||
|
||||
class TestDisplaySummaryTable:
|
||||
def test_azure_summary_shows_display_name_and_subscription_id(self, capsys):
|
||||
provider = SimpleNamespace(
|
||||
type="azure",
|
||||
identity=SimpleNamespace(
|
||||
tenant_domain="tenant.example.com",
|
||||
tenant_ids=["tenant-id"],
|
||||
subscriptions={
|
||||
"subscription-id-1": "Duplicate Subscription",
|
||||
"subscription-id-2": "Duplicate Subscription",
|
||||
},
|
||||
),
|
||||
)
|
||||
output_options = SimpleNamespace(
|
||||
output_directory="out",
|
||||
output_filename="report",
|
||||
output_modes=[],
|
||||
)
|
||||
findings = [
|
||||
SimpleNamespace(
|
||||
status="PASS",
|
||||
muted=False,
|
||||
check_metadata=SimpleNamespace(
|
||||
ServiceName="network",
|
||||
Provider="azure",
|
||||
Severity="low",
|
||||
),
|
||||
)
|
||||
]
|
||||
|
||||
display_summary_table(findings, provider, output_options)
|
||||
|
||||
captured = capsys.readouterr()
|
||||
|
||||
assert "Subscriptions scanned:" in captured.out
|
||||
assert "Duplicate Subscription (subscription-id-1)" in captured.out
|
||||
assert "Duplicate Subscription (subscription-id-2)" in captured.out
|
||||
@@ -0,0 +1,91 @@
|
||||
from prowler.lib.utils.vulnerability_references import (
|
||||
build_finding_reference_url,
|
||||
resolve_vulnerability_reference_urls,
|
||||
)
|
||||
|
||||
|
||||
class TestBuildFindingReferenceUrl:
|
||||
def test_cve_id_returns_cve_org_url(self):
|
||||
assert (
|
||||
build_finding_reference_url("CVE-2023-1234")
|
||||
== "https://www.cve.org/CVERecord?id=CVE-2023-1234"
|
||||
)
|
||||
|
||||
def test_lowercase_cve_id_is_normalized(self):
|
||||
assert (
|
||||
build_finding_reference_url("cve-2024-9999")
|
||||
== "https://www.cve.org/CVERecord?id=CVE-2024-9999"
|
||||
)
|
||||
|
||||
def test_ghsa_id_returns_github_advisory_url(self):
|
||||
assert (
|
||||
build_finding_reference_url("GHSA-abcd-1234-efgh")
|
||||
== "https://github.com/advisories/GHSA-ABCD-1234-EFGH"
|
||||
)
|
||||
|
||||
def test_avd_prefixed_id_strips_prefix_for_hub(self):
|
||||
assert (
|
||||
build_finding_reference_url("AVD-AWS-0001")
|
||||
== "https://hub.prowler.com/check/AWS-0001"
|
||||
)
|
||||
|
||||
def test_clean_trivy_id_uses_hub_directly(self):
|
||||
assert (
|
||||
build_finding_reference_url("AWS-0104")
|
||||
== "https://hub.prowler.com/check/AWS-0104"
|
||||
)
|
||||
|
||||
def test_kubernetes_id_uses_hub(self):
|
||||
assert (
|
||||
build_finding_reference_url("AVD-K8S-0001")
|
||||
== "https://hub.prowler.com/check/K8S-0001"
|
||||
)
|
||||
|
||||
def test_dockerfile_id_uses_hub(self):
|
||||
assert (
|
||||
build_finding_reference_url("AVD-DOCKER-0001")
|
||||
== "https://hub.prowler.com/check/DOCKER-0001"
|
||||
)
|
||||
|
||||
def test_whitespace_is_trimmed(self):
|
||||
assert (
|
||||
build_finding_reference_url(" AZU-0013 ")
|
||||
== "https://hub.prowler.com/check/AZU-0013"
|
||||
)
|
||||
|
||||
|
||||
class TestResolveVulnerabilityReferenceUrls:
|
||||
def test_cve_with_cve_org_reference_uses_it(self):
|
||||
recommendation_url, additional_urls = resolve_vulnerability_reference_urls(
|
||||
vulnerability_id="CVE-2023-1234",
|
||||
references=[
|
||||
"https://avd.aquasec.com/nvd/cve-2023-1234",
|
||||
"https://www.cve.org/CVERecord?id=CVE-2023-1234",
|
||||
"https://nvd.nist.gov/vuln/detail/CVE-2023-1234",
|
||||
],
|
||||
primary_url="https://avd.aquasec.com/nvd/cve-2023-1234",
|
||||
)
|
||||
|
||||
assert recommendation_url == "https://www.cve.org/CVERecord?id=CVE-2023-1234"
|
||||
assert additional_urls == ["https://www.cve.org/CVERecord?id=CVE-2023-1234"]
|
||||
|
||||
def test_cve_without_cve_org_reference_builds_url(self):
|
||||
recommendation_url, additional_urls = resolve_vulnerability_reference_urls(
|
||||
vulnerability_id="CVE-2023-5678",
|
||||
references=["https://nvd.nist.gov/vuln/detail/CVE-2023-5678"],
|
||||
)
|
||||
|
||||
assert recommendation_url == "https://www.cve.org/CVERecord?id=CVE-2023-5678"
|
||||
assert additional_urls == ["https://www.cve.org/CVERecord?id=CVE-2023-5678"]
|
||||
|
||||
def test_non_cve_id_returns_filtered_references(self):
|
||||
recommendation_url, additional_urls = resolve_vulnerability_reference_urls(
|
||||
vulnerability_id="GHSA-abcd-1234-efgh",
|
||||
references=[
|
||||
"https://avd.aquasec.com/nvd/ghsa-abcd-1234-efgh",
|
||||
"https://github.com/advisories/GHSA-abcd-1234-efgh",
|
||||
],
|
||||
)
|
||||
|
||||
assert recommendation_url == ""
|
||||
assert additional_urls == ["https://github.com/advisories/GHSA-abcd-1234-efgh"]
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
from unittest import mock
|
||||
|
||||
import botocore
|
||||
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_ACCOUNT_NUMBER,
|
||||
AWS_REGION_EU_WEST_1,
|
||||
AWS_REGION_US_EAST_1,
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
PROMPT_ARN = (
|
||||
f"arn:aws:bedrock:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:prompt/test-prompt-id"
|
||||
)
|
||||
PROMPT_ID = "test-prompt-id"
|
||||
PROMPT_NAME = "test-prompt"
|
||||
KMS_KEY_ARN = (
|
||||
f"arn:aws:kms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:key/"
|
||||
"12345678-1234-1234-1234-123456789012"
|
||||
)
|
||||
|
||||
|
||||
def mock_make_api_call_with_cmk(self, operation_name, kwarg):
|
||||
"""Mock API call returning a prompt encrypted with a customer-managed KMS key."""
|
||||
if operation_name == "ListPrompts":
|
||||
return {
|
||||
"promptSummaries": [
|
||||
{
|
||||
"id": PROMPT_ID,
|
||||
"name": PROMPT_NAME,
|
||||
"arn": PROMPT_ARN,
|
||||
}
|
||||
]
|
||||
}
|
||||
elif operation_name == "GetPrompt":
|
||||
return {
|
||||
"id": PROMPT_ID,
|
||||
"name": PROMPT_NAME,
|
||||
"arn": PROMPT_ARN,
|
||||
"customerEncryptionKeyArn": KMS_KEY_ARN,
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
def mock_make_api_call_without_cmk(self, operation_name, kwarg):
|
||||
"""Mock API call returning a prompt without a customer-managed KMS key."""
|
||||
if operation_name == "ListPrompts":
|
||||
return {
|
||||
"promptSummaries": [
|
||||
{
|
||||
"id": PROMPT_ID,
|
||||
"name": PROMPT_NAME,
|
||||
"arn": PROMPT_ARN,
|
||||
}
|
||||
]
|
||||
}
|
||||
elif operation_name == "GetPrompt":
|
||||
return {
|
||||
"id": PROMPT_ID,
|
||||
"name": PROMPT_NAME,
|
||||
"arn": PROMPT_ARN,
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
class Test_bedrock_prompt_encrypted_with_cmk:
|
||||
"""Test suite for the bedrock_prompt_encrypted_with_cmk check."""
|
||||
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=lambda self, op, kwarg: make_api_call(self, op, kwarg),
|
||||
)
|
||||
def test_no_prompts(self):
|
||||
"""Test when no prompts exist."""
|
||||
from prowler.providers.aws.services.bedrock.bedrock_service import BedrockAgent
|
||||
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1]
|
||||
)
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_prompt_encrypted_with_cmk.bedrock_prompt_encrypted_with_cmk.bedrock_agent_client",
|
||||
new=BedrockAgent(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_prompt_encrypted_with_cmk.bedrock_prompt_encrypted_with_cmk import (
|
||||
bedrock_prompt_encrypted_with_cmk,
|
||||
)
|
||||
|
||||
check = bedrock_prompt_encrypted_with_cmk()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_with_cmk,
|
||||
)
|
||||
def test_prompt_encrypted_with_cmk(self):
|
||||
"""Test when a prompt is encrypted with a customer-managed KMS key."""
|
||||
from prowler.providers.aws.services.bedrock.bedrock_service import BedrockAgent
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_prompt_encrypted_with_cmk.bedrock_prompt_encrypted_with_cmk.bedrock_agent_client",
|
||||
new=BedrockAgent(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_prompt_encrypted_with_cmk.bedrock_prompt_encrypted_with_cmk import (
|
||||
bedrock_prompt_encrypted_with_cmk,
|
||||
)
|
||||
|
||||
check = bedrock_prompt_encrypted_with_cmk()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Bedrock Prompt {PROMPT_NAME} is encrypted with a customer-managed KMS key."
|
||||
)
|
||||
assert result[0].resource_id == PROMPT_ID
|
||||
assert result[0].resource_arn == PROMPT_ARN
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_without_cmk,
|
||||
)
|
||||
def test_prompt_not_encrypted_with_cmk(self):
|
||||
"""Test when a prompt is not encrypted with a customer-managed KMS key."""
|
||||
from prowler.providers.aws.services.bedrock.bedrock_service import BedrockAgent
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_prompt_encrypted_with_cmk.bedrock_prompt_encrypted_with_cmk.bedrock_agent_client",
|
||||
new=BedrockAgent(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_prompt_encrypted_with_cmk.bedrock_prompt_encrypted_with_cmk import (
|
||||
bedrock_prompt_encrypted_with_cmk,
|
||||
)
|
||||
|
||||
check = bedrock_prompt_encrypted_with_cmk()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Bedrock Prompt {PROMPT_NAME} is not encrypted with a customer-managed KMS key."
|
||||
)
|
||||
assert result[0].resource_id == PROMPT_ID
|
||||
assert result[0].resource_arn == PROMPT_ARN
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
@@ -406,12 +406,14 @@ class TestBedrockPromptPagination:
|
||||
regional_client.get_paginator.assert_called_once_with("list_prompts")
|
||||
paginator.paginate.assert_called_once()
|
||||
|
||||
def test_list_prompts_ignores_audit_resources_filter(self):
|
||||
"""Prompt collection is region-scoped and must ignore audit_resources."""
|
||||
def test_list_prompts_filters_audit_resources(self):
|
||||
"""Prompt collection must honor audit_resources when resource ARNs are scoped."""
|
||||
audit_info = MagicMock()
|
||||
audit_info.audited_partition = "aws"
|
||||
audit_info.audited_account = "123456789012"
|
||||
audit_info.audit_resources = ["arn:aws:s3:::unrelated-resource"]
|
||||
audit_info.audit_resources = [
|
||||
"arn:aws:bedrock:us-east-1:123456789012:prompt/prompt-1"
|
||||
]
|
||||
|
||||
regional_client = MagicMock()
|
||||
regional_client.region = "us-east-1"
|
||||
@@ -424,7 +426,12 @@ class TestBedrockPromptPagination:
|
||||
"id": "prompt-1",
|
||||
"name": "prompt-name-1",
|
||||
"arn": "arn:aws:bedrock:us-east-1:123456789012:prompt/prompt-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "prompt-2",
|
||||
"name": "prompt-name-2",
|
||||
"arn": "arn:aws:bedrock:us-east-1:123456789012:prompt/prompt-2",
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -438,6 +445,14 @@ class TestBedrockPromptPagination:
|
||||
bedrock_agent_service._list_prompts(regional_client)
|
||||
|
||||
assert len(bedrock_agent_service.prompts) == 1
|
||||
assert (
|
||||
"arn:aws:bedrock:us-east-1:123456789012:prompt/prompt-1"
|
||||
in bedrock_agent_service.prompts
|
||||
)
|
||||
assert (
|
||||
"arn:aws:bedrock:us-east-1:123456789012:prompt/prompt-2"
|
||||
not in bedrock_agent_service.prompts
|
||||
)
|
||||
assert "us-east-1" in bedrock_agent_service.prompt_scanned_regions
|
||||
|
||||
def test_list_prompts_error_does_not_mark_region_scanned(self):
|
||||
|
||||
+1020
File diff suppressed because it is too large.
Load diff
+80
@@ -408,3 +408,83 @@ class Test_iam_no_custom_policy_permissive_role_assumption:
|
||||
assert search(
|
||||
"allows permissive STS Role assumption", result[0].status_extended
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
def test_unattached_policy_skipped_when_scan_unused_services_disabled(self):
|
||||
iam_client = client("iam")
|
||||
policy_name = "unattached_permissive_assume_role"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_no_custom_policy_permissive_role_assumption.iam_no_custom_policy_permissive_role_assumption.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_no_custom_policy_permissive_role_assumption.iam_no_custom_policy_permissive_role_assumption import (
|
||||
iam_no_custom_policy_permissive_role_assumption,
|
||||
)
|
||||
|
||||
check = iam_no_custom_policy_permissive_role_assumption()
|
||||
result = check.execute()
|
||||
assert result == []
|
||||
|
||||
@mock_aws
|
||||
def test_attached_policy_fails_when_scan_unused_services_disabled(self):
|
||||
iam_client = client("iam")
|
||||
user_name = "test_user_assume_role"
|
||||
policy_name = "attached_permissive_assume_role"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=arn)
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_no_custom_policy_permissive_role_assumption.iam_no_custom_policy_permissive_role_assumption.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_no_custom_policy_permissive_role_assumption.iam_no_custom_policy_permissive_role_assumption import (
|
||||
iam_no_custom_policy_permissive_role_assumption,
|
||||
)
|
||||
|
||||
check = iam_no_custom_policy_permissive_role_assumption()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_arn == arn
|
||||
assert search(
|
||||
"allows permissive STS Role assumption", result[0].status_extended
|
||||
)
|
||||
+83
@@ -1261,3 +1261,86 @@ class Test_iam_policy_allows_privilege_escalation:
|
||||
permissions
|
||||
]:
|
||||
assert search(permission, finding.status_extended)
|
||||
|
||||
@mock_aws
|
||||
def test_unattached_policy_skipped_when_scan_unused_services_disabled(self):
|
||||
iam_client = client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
policy_name = "unattached_privilege_escalation"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "iam:CreateAccessKey", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)
|
||||
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import (
|
||||
iam_policy_allows_privilege_escalation,
|
||||
)
|
||||
|
||||
check = iam_policy_allows_privilege_escalation()
|
||||
result = check.execute()
|
||||
assert result == []
|
||||
|
||||
@mock_aws
|
||||
def test_attached_policy_fails_when_scan_unused_services_disabled(self):
|
||||
iam_client = client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
user_name = "test_user_privesc"
|
||||
policy_name = "attached_privilege_escalation"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "iam:CreateAccessKey", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
policy_arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=policy_arn)
|
||||
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import (
|
||||
iam_policy_allows_privilege_escalation,
|
||||
)
|
||||
|
||||
check = iam_policy_allows_privilege_escalation()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_arn == policy_arn
|
||||
assert search(
|
||||
f"Custom Policy {policy_arn} allows privilege escalation",
|
||||
result[0].status_extended,
|
||||
)
|
||||
+75
@@ -207,3 +207,78 @@ class Test_iam_policy_no_full_access_to_cloudtrail:
|
||||
assert result[0].resource_id == "policy_no_cloudtrail_full_no_actions"
|
||||
assert result[0].resource_arn == arn
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_aws
|
||||
def test_unattached_policy_skipped_when_scan_unused_services_disabled(self):
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
iam_client = client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
policy_name = "unattached_cloudtrail_full"
|
||||
policy_document_full_access = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "cloudtrail:*", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document_full_access)
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_policy_no_full_access_to_cloudtrail.iam_policy_no_full_access_to_cloudtrail.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_no_full_access_to_cloudtrail.iam_policy_no_full_access_to_cloudtrail import (
|
||||
iam_policy_no_full_access_to_cloudtrail,
|
||||
)
|
||||
|
||||
check = iam_policy_no_full_access_to_cloudtrail()
|
||||
result = check.execute()
|
||||
assert result == []
|
||||
|
||||
@mock_aws
|
||||
def test_attached_policy_fails_when_scan_unused_services_disabled(self):
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
iam_client = client("iam", region_name=AWS_REGION_US_EAST_1)
|
||||
user_name = "test_user_cloudtrail"
|
||||
policy_name = "attached_cloudtrail_full"
|
||||
policy_document_full_access = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "cloudtrail:*", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document_full_access)
|
||||
)["Policy"]["Arn"]
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=arn)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_policy_no_full_access_to_cloudtrail.iam_policy_no_full_access_to_cloudtrail.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_no_full_access_to_cloudtrail.iam_policy_no_full_access_to_cloudtrail import (
|
||||
iam_policy_no_full_access_to_cloudtrail,
|
||||
)
|
||||
|
||||
check = iam_policy_no_full_access_to_cloudtrail()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Custom Policy {policy_name} allows 'cloudtrail:*' privileges."
|
||||
)
|
||||
assert result[0].resource_arn == arn
|
||||
+75
@@ -329,6 +329,81 @@ class Test_iam_policy_no_full_access_to_kms_with_unicode:
|
||||
assert result[0].resource_arn == arn
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_aws
|
||||
def test_unattached_policy_skipped_when_scan_unused_services_disabled(self):
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
iam_client = client("iam")
|
||||
policy_name = "unattached_kms_full"
|
||||
policy_document_full_access = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "kms:*", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document_full_access)
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_policy_no_full_access_to_kms.iam_policy_no_full_access_to_kms.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_no_full_access_to_kms.iam_policy_no_full_access_to_kms import (
|
||||
iam_policy_no_full_access_to_kms,
|
||||
)
|
||||
|
||||
check = iam_policy_no_full_access_to_kms()
|
||||
result = check.execute()
|
||||
assert result == []
|
||||
|
||||
@mock_aws
|
||||
def test_attached_policy_fails_when_scan_unused_services_disabled(self):
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
iam_client = client("iam")
|
||||
user_name = "test_user_kms"
|
||||
policy_name = "attached_kms_full"
|
||||
policy_document_full_access = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{"Effect": "Allow", "Action": "kms:*", "Resource": "*"},
|
||||
],
|
||||
}
|
||||
arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document_full_access)
|
||||
)["Policy"]["Arn"]
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=arn)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_policy_no_full_access_to_kms.iam_policy_no_full_access_to_kms.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_no_full_access_to_kms.iam_policy_no_full_access_to_kms import (
|
||||
iam_policy_no_full_access_to_kms,
|
||||
)
|
||||
|
||||
check = iam_policy_no_full_access_to_kms()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Custom Policy {policy_name} allows 'kms:*' privileges."
|
||||
)
|
||||
assert result[0].resource_arn == arn
|
||||
|
||||
@mock_aws
|
||||
def test_policy_full_access_and_full_deny_to_kms(self):
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
+81
@@ -507,3 +507,84 @@ class Test_iam_policy_no_wildcard_marketplace_subscribe:
|
||||
check = iam_policy_no_wildcard_marketplace_subscribe()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_unattached_policy_skipped_when_scan_unused_services_disabled(self):
|
||||
"""No FAIL for an unattached risky policy when --scan-unused-services is off."""
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
iam_client = client("iam")
|
||||
policy_name = "unattached_marketplace_subscribe"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "aws-marketplace:Subscribe",
|
||||
"Resource": "*",
|
||||
},
|
||||
],
|
||||
}
|
||||
iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
f"{CHECK_MODULE_PATH}.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_no_wildcard_marketplace_subscribe.iam_policy_no_wildcard_marketplace_subscribe import (
|
||||
iam_policy_no_wildcard_marketplace_subscribe,
|
||||
)
|
||||
|
||||
check = iam_policy_no_wildcard_marketplace_subscribe()
|
||||
result = check.execute()
|
||||
assert result == []
|
||||
|
||||
@mock_aws
|
||||
def test_attached_policy_fails_when_scan_unused_services_disabled(self):
|
||||
"""Attached risky policy still FAILs when --scan-unused-services is off."""
|
||||
aws_provider = set_mocked_aws_provider(
|
||||
[AWS_REGION_US_EAST_1], scan_unused_services=False
|
||||
)
|
||||
iam_client = client("iam")
|
||||
user_name = "test_user_marketplace"
|
||||
policy_name = "attached_marketplace_subscribe"
|
||||
policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "aws-marketplace:Subscribe",
|
||||
"Resource": "*",
|
||||
},
|
||||
],
|
||||
}
|
||||
arn = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=dumps(policy_document)
|
||||
)["Policy"]["Arn"]
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=arn)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
f"{CHECK_MODULE_PATH}.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_policy_no_wildcard_marketplace_subscribe.iam_policy_no_wildcard_marketplace_subscribe import (
|
||||
iam_policy_no_wildcard_marketplace_subscribe,
|
||||
)
|
||||
|
||||
check = iam_policy_no_wildcard_marketplace_subscribe()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_arn == arn
|
||||
+252
@@ -190,6 +190,258 @@ class Test_iam_role_access_not_stale_to_bedrock:
|
||||
assert "has never used them" in result[0].status_extended
|
||||
assert "Role" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_no_roles_listed(self):
|
||||
"""No findings when iam.roles is None (short-circuit)."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
iam.roles = None
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_role_access_not_stale_to_bedrock.iam_role_access_not_stale_to_bedrock import (
|
||||
iam_role_access_not_stale_to_bedrock,
|
||||
)
|
||||
|
||||
check = iam_role_access_not_stale_to_bedrock()
|
||||
assert check.execute() == []
|
||||
|
||||
@mock_aws
|
||||
def test_role_without_bedrock_permissions(self):
|
||||
"""Role with non-Bedrock services is skipped."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, Role
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_role = Role(
|
||||
name=IAM_ROLE_NAME,
|
||||
arn=IAM_ROLE_ARN,
|
||||
assume_role_policy={},
|
||||
is_service_role=False,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.roles = [mock_role]
|
||||
iam.role_last_accessed_services = {
|
||||
ROLE_DATA: [
|
||||
{"ServiceNamespace": "iam", "ServiceName": "IAM"},
|
||||
{"ServiceNamespace": "s3", "ServiceName": "S3"},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_role_access_not_stale_to_bedrock.iam_role_access_not_stale_to_bedrock import (
|
||||
iam_role_access_not_stale_to_bedrock,
|
||||
)
|
||||
|
||||
check = iam_role_access_not_stale_to_bedrock()
|
||||
assert len(check.execute()) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_role_bedrock_access_with_string_date(self):
|
||||
"""PASS when LastAuthenticated is an ISO string instead of a datetime object."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, Role
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_role = Role(
|
||||
name=IAM_ROLE_NAME,
|
||||
arn=IAM_ROLE_ARN,
|
||||
assume_role_policy={},
|
||||
is_service_role=False,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.roles = [mock_role]
|
||||
|
||||
last_access_date = datetime.now(timezone.utc) - timedelta(days=5)
|
||||
iam.role_last_accessed_services = {
|
||||
ROLE_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "bedrock",
|
||||
"ServiceName": "Amazon Bedrock",
|
||||
"LastAuthenticated": last_access_date.isoformat(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_role_access_not_stale_to_bedrock.iam_role_access_not_stale_to_bedrock import (
|
||||
iam_role_access_not_stale_to_bedrock,
|
||||
)
|
||||
|
||||
check = iam_role_access_not_stale_to_bedrock()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
|
||||
@mock_aws
|
||||
def test_role_bedrock_access_at_exact_threshold(self):
|
||||
"""PASS when role accessed Bedrock exactly at the 60-day boundary."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, Role
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_role = Role(
|
||||
name=IAM_ROLE_NAME,
|
||||
arn=IAM_ROLE_ARN,
|
||||
assume_role_policy={},
|
||||
is_service_role=False,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.roles = [mock_role]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=60)
|
||||
iam.role_last_accessed_services = {
|
||||
ROLE_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "bedrock",
|
||||
"ServiceName": "Amazon Bedrock",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_role_access_not_stale_to_bedrock.iam_role_access_not_stale_to_bedrock import (
|
||||
iam_role_access_not_stale_to_bedrock,
|
||||
)
|
||||
|
||||
check = iam_role_access_not_stale_to_bedrock()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert "60 days ago" in result[0].status_extended
|
||||
assert "threshold: 60 days" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_role_bedrock_access_one_day_over_threshold(self):
|
||||
"""FAIL when role accessed Bedrock 61 days ago."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, Role
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_role = Role(
|
||||
name=IAM_ROLE_NAME,
|
||||
arn=IAM_ROLE_ARN,
|
||||
assume_role_policy={},
|
||||
is_service_role=False,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.roles = [mock_role]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=61)
|
||||
iam.role_last_accessed_services = {
|
||||
ROLE_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "bedrock",
|
||||
"ServiceName": "Amazon Bedrock",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_role_access_not_stale_to_bedrock.iam_role_access_not_stale_to_bedrock import (
|
||||
iam_role_access_not_stale_to_bedrock,
|
||||
)
|
||||
|
||||
check = iam_role_access_not_stale_to_bedrock()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "61 days" in result[0].status_extended
|
||||
assert "threshold: 60 days" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_custom_threshold_via_audit_config(self):
|
||||
"""Custom threshold from audit_config is respected for roles."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, Role
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
iam.audit_config = {"max_unused_bedrock_access_days": 30}
|
||||
|
||||
mock_role = Role(
|
||||
name=IAM_ROLE_NAME,
|
||||
arn=IAM_ROLE_ARN,
|
||||
assume_role_policy={},
|
||||
is_service_role=False,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.roles = [mock_role]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=45)
|
||||
iam.role_last_accessed_services = {
|
||||
ROLE_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "bedrock",
|
||||
"ServiceName": "Amazon Bedrock",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_role_access_not_stale_to_bedrock.iam_role_access_not_stale_to_bedrock import (
|
||||
iam_role_access_not_stale_to_bedrock,
|
||||
)
|
||||
|
||||
check = iam_role_access_not_stale_to_bedrock()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "45 days" in result[0].status_extended
|
||||
assert "threshold: 30 days" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_role_tags_are_populated(self):
|
||||
"""Verify resource_tags are populated from the role object."""
|
||||
|
||||
+623
@@ -0,0 +1,623 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest import mock
|
||||
|
||||
from moto import mock_aws
|
||||
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_ACCOUNT_NUMBER,
|
||||
AWS_REGION_US_EAST_1,
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
IAM_USER_NAME = "test-user"
|
||||
IAM_USER_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:user/{IAM_USER_NAME}"
|
||||
USER_DATA = (IAM_USER_NAME, IAM_USER_ARN)
|
||||
|
||||
CHECK_MODULE = (
|
||||
"prowler.providers.aws.services.iam."
|
||||
"iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker"
|
||||
)
|
||||
|
||||
|
||||
class Test_iam_user_access_not_stale_to_sagemaker:
|
||||
@mock_aws
|
||||
def test_no_users_with_sagemaker_permissions(self):
|
||||
"""No findings when no users have SageMaker in last accessed services."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
iam.last_accessed_services = {}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
assert len(check.execute()) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_user_without_sagemaker_permissions(self):
|
||||
"""User with non-SageMaker services is skipped."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{"ServiceNamespace": "iam", "ServiceName": "IAM"},
|
||||
{"ServiceNamespace": "s3", "ServiceName": "S3"},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
assert len(check.execute()) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_user_sagemaker_access_recent(self):
|
||||
"""PASS when user accessed SageMaker within the threshold."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=10)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert "accessed SageMaker" in result[0].status_extended
|
||||
assert IAM_USER_NAME in result[0].status_extended
|
||||
assert result[0].resource_id == IAM_USER_NAME
|
||||
assert result[0].resource_arn == IAM_USER_ARN
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
|
||||
@mock_aws
|
||||
def test_user_sagemaker_access_stale(self):
|
||||
"""FAIL when user last accessed SageMaker more than 90 days ago."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=120)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "has not accessed SageMaker" in result[0].status_extended
|
||||
assert "120 days" in result[0].status_extended
|
||||
assert IAM_USER_NAME in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_user_sagemaker_never_accessed(self):
|
||||
"""FAIL when user has SageMaker permissions but has never used them."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "has never used them" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_custom_threshold_via_audit_config(self):
|
||||
"""Custom threshold from audit_config is respected."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
iam.audit_config = {"max_unused_sagemaker_access_days": 30}
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=45)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "45 days" in result[0].status_extended
|
||||
assert "threshold: 30 days" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_user_sagemaker_access_at_exact_threshold(self):
|
||||
"""PASS when user accessed SageMaker exactly at the 90-day boundary."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=90)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert "90 days ago" in result[0].status_extended
|
||||
assert "threshold: 90 days" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_user_sagemaker_access_one_day_over_threshold(self):
|
||||
"""FAIL when user accessed SageMaker 91 days ago."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=91)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "91 days" in result[0].status_extended
|
||||
assert "threshold: 90 days" in result[0].status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_user_sagemaker_access_with_string_date(self):
|
||||
"""PASS when LastAuthenticated is an ISO string instead of a datetime object."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_access_date = datetime.now(timezone.utc) - timedelta(days=5)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_access_date.isoformat(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
|
||||
@mock_aws
|
||||
def test_user_tags_are_populated(self):
|
||||
"""Verify resource_tags are populated from the user object."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
user_tags = [{"Key": "Environment", "Value": "production"}]
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
tags=user_tags,
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=10)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_tags == user_tags
|
||||
|
||||
@mock_aws
|
||||
def test_multiple_users_mixed_results(self):
|
||||
"""Multiple users: one recent (PASS), one stale (FAIL), one without SageMaker (skipped)."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
recent_user_name = "recent-user"
|
||||
recent_user_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:user/{recent_user_name}"
|
||||
stale_user_name = "stale-user"
|
||||
stale_user_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:user/{stale_user_name}"
|
||||
no_sagemaker_user_name = "no-sagemaker-user"
|
||||
no_sagemaker_user_arn = (
|
||||
f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:user/{no_sagemaker_user_name}"
|
||||
)
|
||||
|
||||
iam.users = [
|
||||
User(
|
||||
name=recent_user_name,
|
||||
arn=recent_user_arn,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
),
|
||||
User(
|
||||
name=stale_user_name,
|
||||
arn=stale_user_arn,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
),
|
||||
User(
|
||||
name=no_sagemaker_user_name,
|
||||
arn=no_sagemaker_user_arn,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
),
|
||||
]
|
||||
|
||||
recent_access = datetime.now(timezone.utc) - timedelta(days=10)
|
||||
stale_access = datetime.now(timezone.utc) - timedelta(days=120)
|
||||
iam.last_accessed_services = {
|
||||
(recent_user_name, recent_user_arn): [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": recent_access,
|
||||
},
|
||||
],
|
||||
(stale_user_name, stale_user_arn): [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": stale_access,
|
||||
},
|
||||
],
|
||||
(no_sagemaker_user_name, no_sagemaker_user_arn): [
|
||||
{"ServiceNamespace": "s3", "ServiceName": "S3"},
|
||||
],
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
results_by_id = {r.resource_id: r for r in result}
|
||||
|
||||
assert results_by_id[recent_user_name].status == "PASS"
|
||||
assert (
|
||||
"accessed SageMaker" in results_by_id[recent_user_name].status_extended
|
||||
)
|
||||
|
||||
assert results_by_id[stale_user_name].status == "FAIL"
|
||||
assert (
|
||||
"has not accessed SageMaker"
|
||||
in results_by_id[stale_user_name].status_extended
|
||||
)
|
||||
assert "120 days" in results_by_id[stale_user_name].status_extended
|
||||
|
||||
assert no_sagemaker_user_name not in results_by_id
|
||||
|
||||
@mock_aws
|
||||
def test_user_arn_not_in_users_list(self):
|
||||
"""No findings when last_accessed_services entries do not match any iam.users."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
iam.users = []
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=10)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
assert check.execute() == []
|
||||
|
||||
@mock_aws
|
||||
def test_sagemaker_among_multiple_services(self):
|
||||
"""SageMaker entry is correctly found when mixed with other services."""
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM, User
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
mock_user = User(
|
||||
name=IAM_USER_NAME,
|
||||
arn=IAM_USER_ARN,
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
iam.users = [mock_user]
|
||||
|
||||
last_authenticated = datetime.now(timezone.utc) - timedelta(days=15)
|
||||
iam.last_accessed_services = {
|
||||
USER_DATA: [
|
||||
{"ServiceNamespace": "iam", "ServiceName": "IAM"},
|
||||
{"ServiceNamespace": "s3", "ServiceName": "S3"},
|
||||
{
|
||||
"ServiceNamespace": "sagemaker",
|
||||
"ServiceName": "Amazon SageMaker",
|
||||
"LastAuthenticated": last_authenticated,
|
||||
},
|
||||
{"ServiceNamespace": "ec2", "ServiceName": "EC2"},
|
||||
]
|
||||
}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(f"{CHECK_MODULE}.iam_client", new=iam),
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_user_access_not_stale_to_sagemaker.iam_user_access_not_stale_to_sagemaker import (
|
||||
iam_user_access_not_stale_to_sagemaker,
|
||||
)
|
||||
|
||||
check = iam_user_access_not_stale_to_sagemaker()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert "accessed SageMaker" in result[0].status_extended
|
||||
assert "15 days ago" in result[0].status_extended
|
||||
+54
-7
@@ -93,6 +93,8 @@ class Test_s3_bucket_shadow_resource_vulnerability:
|
||||
|
||||
@mock_aws
|
||||
def test_bucket_not_predictable(self):
|
||||
# A bucket whose name does not match any predictable service pattern
|
||||
# is not a shadow resource and must not produce any finding.
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
aws_provider.identity.identity_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
@@ -113,6 +115,55 @@ class Test_s3_bucket_shadow_resource_vulnerability:
|
||||
s3_client.provider = aws_provider
|
||||
s3_client._head_bucket = mock.MagicMock(return_value=False)
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.s3.s3_bucket_shadow_resource_vulnerability.s3_bucket_shadow_resource_vulnerability.s3_client",
|
||||
new=s3_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.s3.s3_bucket_shadow_resource_vulnerability.s3_bucket_shadow_resource_vulnerability import (
|
||||
s3_bucket_shadow_resource_vulnerability,
|
||||
)
|
||||
|
||||
check = s3_bucket_shadow_resource_vulnerability()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_only_predictable_bucket_reported_among_many(self):
|
||||
# With a mix of buckets, only the one matching a predictable pattern
|
||||
# must produce a finding; the rest must be silent.
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
aws_provider.identity.identity_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
predictable_bucket = f"sagemaker-{AWS_REGION_US_EAST_1}-{AWS_ACCOUNT_NUMBER}"
|
||||
plain_buckets = [
|
||||
"config-bucket-data",
|
||||
"my-app-data-bucket",
|
||||
"guardduty-findings-store",
|
||||
]
|
||||
|
||||
s3_client = mock.MagicMock()
|
||||
s3_client.audited_canonical_id = AWS_ACCOUNT_NUMBER
|
||||
s3_client.audited_partition = "aws"
|
||||
s3_client.buckets = {
|
||||
name: Bucket(
|
||||
name=name,
|
||||
arn=f"arn:aws:s3:::{name}",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
owner_id=AWS_ACCOUNT_NUMBER,
|
||||
tags=[],
|
||||
)
|
||||
for name in [predictable_bucket, *plain_buckets]
|
||||
}
|
||||
s3_client.provider = aws_provider
|
||||
s3_client._head_bucket = mock.MagicMock(return_value=False)
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
@@ -132,14 +183,10 @@ class Test_s3_bucket_shadow_resource_vulnerability:
|
||||
|
||||
assert len(result) == 1
|
||||
report = result[0]
|
||||
|
||||
# Test all report attributes
|
||||
assert report.status == "PASS"
|
||||
assert report.region == AWS_REGION_US_EAST_1
|
||||
assert report.resource_id == bucket_name
|
||||
assert report.resource_arn == f"arn:aws:s3:::{bucket_name}"
|
||||
assert report.resource_tags == [{"Key": "Project", "Value": "test-project"}]
|
||||
assert "is not a known shadow resource" in report.status_extended
|
||||
assert report.resource_id == predictable_bucket
|
||||
assert "SageMaker" in report.status_extended
|
||||
assert "is correctly owned by the audited account" in report.status_extended
|
||||
|
||||
@mock_aws
|
||||
def test_shadow_resource_in_other_account(self):
|
||||
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_service import Domain
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_ACCOUNT_NUMBER,
|
||||
AWS_REGION_EU_WEST_1,
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
test_domain_name = "test-domain"
|
||||
test_domain_id = "d-testdomain123"
|
||||
domain_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:domain/{test_domain_id}"
|
||||
test_sso_instance_id = "app-test-instance-id"
|
||||
test_sso_application_arn = (
|
||||
f"arn:aws:sso::{AWS_ACCOUNT_NUMBER}:application/sagemaker/apl-test"
|
||||
)
|
||||
|
||||
|
||||
class Test_sagemaker_domain_sso_configured:
|
||||
def test_no_domains(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_domains = []
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured import (
|
||||
sagemaker_domain_sso_configured,
|
||||
)
|
||||
|
||||
check = sagemaker_domain_sso_configured()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_domain_sso_configured_with_instance_id(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_domains = [
|
||||
Domain(
|
||||
domain_id=test_domain_id,
|
||||
name=test_domain_name,
|
||||
arn=domain_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
auth_mode="SSO",
|
||||
single_sign_on_managed_application_instance_id=test_sso_instance_id,
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured import (
|
||||
sagemaker_domain_sso_configured,
|
||||
)
|
||||
|
||||
check = sagemaker_domain_sso_configured()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker domain {test_domain_name} is configured with SSO authentication and is associated with an IAM Identity Center instance."
|
||||
)
|
||||
assert result[0].resource_id == test_domain_name
|
||||
assert result[0].resource_arn == domain_arn
|
||||
|
||||
def test_domain_sso_configured_with_application_arn(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_domains = [
|
||||
Domain(
|
||||
domain_id=test_domain_id,
|
||||
name=test_domain_name,
|
||||
arn=domain_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
auth_mode="SSO",
|
||||
single_sign_on_application_arn=test_sso_application_arn,
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured import (
|
||||
sagemaker_domain_sso_configured,
|
||||
)
|
||||
|
||||
check = sagemaker_domain_sso_configured()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker domain {test_domain_name} is configured with SSO authentication and is associated with an IAM Identity Center instance."
|
||||
)
|
||||
|
||||
def test_domain_sso_without_identity_center(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_domains = [
|
||||
Domain(
|
||||
domain_id=test_domain_id,
|
||||
name=test_domain_name,
|
||||
arn=domain_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
auth_mode="SSO",
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured import (
|
||||
sagemaker_domain_sso_configured,
|
||||
)
|
||||
|
||||
check = sagemaker_domain_sso_configured()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker domain {test_domain_name} is configured with SSO authentication but is not associated with an IAM Identity Center instance."
|
||||
)
|
||||
assert result[0].resource_id == test_domain_name
|
||||
assert result[0].resource_arn == domain_arn
|
||||
|
||||
def test_domain_iam_mode(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_domains = [
|
||||
Domain(
|
||||
domain_id=test_domain_id,
|
||||
name=test_domain_name,
|
||||
arn=domain_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
auth_mode="IAM",
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured import (
|
||||
sagemaker_domain_sso_configured,
|
||||
)
|
||||
|
||||
check = sagemaker_domain_sso_configured()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker domain {test_domain_name} is not configured with SSO authentication, current mode is IAM."
|
||||
)
|
||||
assert result[0].resource_id == test_domain_name
|
||||
assert result[0].resource_arn == domain_arn
|
||||
|
||||
def test_domain_auth_mode_unknown(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_domains = [
|
||||
Domain(
|
||||
domain_id=test_domain_id,
|
||||
name=test_domain_name,
|
||||
arn=domain_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_domain_sso_configured.sagemaker_domain_sso_configured import (
|
||||
sagemaker_domain_sso_configured,
|
||||
)
|
||||
|
||||
check = sagemaker_domain_sso_configured()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker domain {test_domain_name} is not configured with SSO authentication, current mode is unknown."
|
||||
)
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_service import ModelRegistry
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_ACCOUNT_NUMBER,
|
||||
AWS_REGION_EU_WEST_1,
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
registry_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:model-registry/unknown"
|
||||
|
||||
|
||||
class Test_sagemaker_models_registry_in_use:
|
||||
def test_no_registries(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_model_registries = []
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use import (
|
||||
sagemaker_models_registry_in_use,
|
||||
)
|
||||
|
||||
check = sagemaker_models_registry_in_use()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_registry_no_groups(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_model_registries = [
|
||||
ModelRegistry(
|
||||
name="SageMaker Model Registry",
|
||||
arn=registry_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
has_groups=False,
|
||||
has_approved_packages=False,
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use import (
|
||||
sagemaker_models_registry_in_use,
|
||||
)
|
||||
|
||||
check = sagemaker_models_registry_in_use()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker Model Registry in region {AWS_REGION_EU_WEST_1} has no Model Package Groups."
|
||||
)
|
||||
assert result[0].resource_id == "SageMaker Model Registry"
|
||||
assert result[0].resource_arn == registry_arn
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
def test_registry_groups_no_approved_packages(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_model_registries = [
|
||||
ModelRegistry(
|
||||
name="SageMaker Model Registry",
|
||||
arn=registry_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
has_groups=True,
|
||||
has_approved_packages=False,
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use import (
|
||||
sagemaker_models_registry_in_use,
|
||||
)
|
||||
|
||||
check = sagemaker_models_registry_in_use()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker Model Registry in region {AWS_REGION_EU_WEST_1} has Model Package Groups but no approved model packages."
|
||||
)
|
||||
assert result[0].resource_id == "SageMaker Model Registry"
|
||||
assert result[0].resource_arn == registry_arn
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
def test_registry_with_approved_packages(self):
|
||||
sagemaker_client = mock.MagicMock
|
||||
sagemaker_client.sagemaker_model_registries = [
|
||||
ModelRegistry(
|
||||
name="SageMaker Model Registry",
|
||||
arn=registry_arn,
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
has_groups=True,
|
||||
has_approved_packages=True,
|
||||
)
|
||||
]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use.sagemaker_client",
|
||||
sagemaker_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.sagemaker.sagemaker_models_registry_in_use.sagemaker_models_registry_in_use import (
|
||||
sagemaker_models_registry_in_use,
|
||||
)
|
||||
|
||||
check = sagemaker_models_registry_in_use()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SageMaker Model Registry in region {AWS_REGION_EU_WEST_1} has at least one approved model package."
|
||||
)
|
||||
assert result[0].resource_id == "SageMaker Model Registry"
|
||||
assert result[0].resource_arn == registry_arn
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
@@ -13,6 +13,11 @@ from tests.providers.aws.utils import (
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
test_model_package_group_name = "test-model-package-group"
|
||||
test_model_package_group_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:model-package-group/{test_model_package_group_name}"
|
||||
test_model_package_name = "test-model-package"
|
||||
test_model_package_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:model-package/{test_model_package_name}/1"
|
||||
|
||||
test_notebook_instance = "test-notebook-instance"
|
||||
notebook_instance_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:notebook-instance/{test_notebook_instance}"
|
||||
test_model = "test-model"
|
||||
@@ -26,6 +31,13 @@ kms_key_id = str(uuid4())
|
||||
endpoint_config_name = "endpoint-config-test"
|
||||
endpoint_config_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:endpoint-config/{endpoint_config_name}"
|
||||
prod_variant_name = "Variant1"
|
||||
test_domain_name = "test-domain"
|
||||
test_domain_id = "d-testdomain123"
|
||||
test_domain_arn = f"arn:aws:sagemaker:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:domain/{test_domain_id}"
|
||||
test_sso_instance_id = "app-test-instance-id"
|
||||
test_sso_application_arn = (
|
||||
f"arn:aws:sso::{AWS_ACCOUNT_NUMBER}:application/sagemaker/apl-test"
|
||||
)
|
||||
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
@@ -87,6 +99,25 @@ def mock_make_api_call(self, operation_name, kwarg):
|
||||
"EnableNetworkIsolation": True,
|
||||
"EnableInterContainerTrafficEncryption": True,
|
||||
}
|
||||
if operation_name == "ListModelPackageGroups":
|
||||
return {
|
||||
"ModelPackageGroupSummaryList": [
|
||||
{
|
||||
"ModelPackageGroupName": test_model_package_group_name,
|
||||
"ModelPackageGroupArn": test_model_package_group_arn,
|
||||
},
|
||||
]
|
||||
}
|
||||
if operation_name == "ListModelPackages":
|
||||
return {
|
||||
"ModelPackageSummaryList": [
|
||||
{
|
||||
"ModelPackageName": test_model_package_name,
|
||||
"ModelPackageArn": test_model_package_arn,
|
||||
"ModelApprovalStatus": "Approved",
|
||||
},
|
||||
]
|
||||
}
|
||||
if operation_name == "ListTags":
|
||||
return {
|
||||
"Tags": [
|
||||
@@ -115,6 +146,25 @@ def mock_make_api_call(self, operation_name, kwarg):
|
||||
},
|
||||
]
|
||||
}
|
||||
if operation_name == "ListDomains":
|
||||
return {
|
||||
"Domains": [
|
||||
{
|
||||
"DomainId": test_domain_id,
|
||||
"DomainName": test_domain_name,
|
||||
"DomainArn": test_domain_arn,
|
||||
},
|
||||
],
|
||||
}
|
||||
if operation_name == "DescribeDomain":
|
||||
return {
|
||||
"DomainId": test_domain_id,
|
||||
"DomainName": test_domain_name,
|
||||
"DomainArn": test_domain_arn,
|
||||
"AuthMode": "SSO",
|
||||
"SingleSignOnManagedApplicationInstanceId": test_sso_instance_id,
|
||||
"SingleSignOnApplicationArn": test_sso_application_arn,
|
||||
}
|
||||
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
@@ -249,6 +299,33 @@ class Test_SageMaker_Service:
|
||||
else:
|
||||
assert prod_variant.initial_instance_count == 2
|
||||
|
||||
# Test SageMaker list domains
|
||||
def test_list_domains(self):
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
sagemaker = SageMaker(aws_provider)
|
||||
assert len(sagemaker.sagemaker_domains) == 1
|
||||
assert sagemaker.sagemaker_domains[0].domain_id == test_domain_id
|
||||
assert sagemaker.sagemaker_domains[0].name == test_domain_name
|
||||
assert sagemaker.sagemaker_domains[0].arn == test_domain_arn
|
||||
assert sagemaker.sagemaker_domains[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
# Test SageMaker describe domain
|
||||
def test_describe_domain(self):
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
sagemaker = SageMaker(aws_provider)
|
||||
assert len(sagemaker.sagemaker_domains) == 1
|
||||
assert sagemaker.sagemaker_domains[0].auth_mode == "SSO"
|
||||
assert (
|
||||
sagemaker.sagemaker_domains[
|
||||
0
|
||||
].single_sign_on_managed_application_instance_id
|
||||
== test_sso_instance_id
|
||||
)
|
||||
assert (
|
||||
sagemaker.sagemaker_domains[0].single_sign_on_application_arn
|
||||
== test_sso_application_arn
|
||||
)
|
||||
|
||||
# Test SageMaker _list_tags_for_resource
|
||||
def test_list_tags_for_resource_calls_client(self):
|
||||
"""Test that _list_tags_for_resource calls the correct AWS client and updates the resource."""
|
||||
@@ -312,14 +389,47 @@ class Test_SageMaker_Service:
|
||||
patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_service.SageMaker._list_endpoint_configs"
|
||||
),
|
||||
patch(
|
||||
"prowler.providers.aws.services.sagemaker.sagemaker_service.SageMaker._list_domains"
|
||||
),
|
||||
):
|
||||
sagemaker_service = SageMaker(audit_info)
|
||||
|
||||
# Check that __threading_call__ was called for _list_tags_for_resource
|
||||
# (at least 4 calls expected, one for each resource type)
|
||||
# (one for each resource type: models, notebooks, training jobs, endpoint configs, domains)
|
||||
tag_calls = [
|
||||
c
|
||||
for c in mock_threading_call.call_args_list
|
||||
if c[0][0] == sagemaker_service._list_tags_for_resource
|
||||
]
|
||||
assert len(tag_calls) == 4
|
||||
assert len(tag_calls) == 5
|
||||
|
||||
# Test SageMaker list model package groups
|
||||
def test_list_model_package_groups(self):
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
sagemaker = SageMaker(aws_provider)
|
||||
assert len(sagemaker.sagemaker_model_registries) == 1
|
||||
registry = sagemaker.sagemaker_model_registries[0]
|
||||
assert registry.region == AWS_REGION_EU_WEST_1
|
||||
assert registry.has_groups is True
|
||||
assert registry.has_approved_packages is True
|
||||
|
||||
def test_list_model_package_groups_access_denied(self):
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
def mock_access_denied(self, operation_name, kwarg):
|
||||
if operation_name == "ListModelPackageGroups":
|
||||
raise botocore.exceptions.ClientError(
|
||||
{
|
||||
"Error": {
|
||||
"Code": "AccessDeniedException",
|
||||
"Message": "User is not authorized to perform sagemaker:ListModelPackageGroups",
|
||||
}
|
||||
},
|
||||
"ListModelPackageGroups",
|
||||
)
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
with patch("botocore.client.BaseClient._make_api_call", new=mock_access_denied):
|
||||
sagemaker = SageMaker(aws_provider)
|
||||
assert sagemaker.sagemaker_model_registries == []
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
from unittest import mock
|
||||
|
||||
import botocore
|
||||
from boto3 import client
|
||||
from moto import mock_aws
|
||||
|
||||
from prowler.providers.aws.services.ses.ses_service import SES
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_ACCOUNT_NUMBER,
|
||||
AWS_REGION_EU_WEST_1,
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call_dkim_pass(self, operation_name, kwarg):
|
||||
if operation_name == "ListEmailIdentities":
|
||||
return {
|
||||
"EmailIdentities": [
|
||||
{
|
||||
"IdentityType": "DOMAIN",
|
||||
"IdentityName": "test-domain-dkim-pass",
|
||||
}
|
||||
],
|
||||
}
|
||||
elif operation_name == "GetEmailIdentity":
|
||||
return {
|
||||
"Policies": {},
|
||||
"Tags": [],
|
||||
"DkimAttributes": {
|
||||
"Status": "SUCCESS",
|
||||
"SigningEnabled": True,
|
||||
"SigningAttributesOrigin": "AWS_SES",
|
||||
},
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
def mock_make_api_call_dkim_fail_not_started(self, operation_name, kwarg):
|
||||
if operation_name == "ListEmailIdentities":
|
||||
return {
|
||||
"EmailIdentities": [
|
||||
{
|
||||
"IdentityType": "DOMAIN",
|
||||
"IdentityName": "test-domain-dkim-not-started",
|
||||
}
|
||||
],
|
||||
}
|
||||
elif operation_name == "GetEmailIdentity":
|
||||
return {
|
||||
"Policies": {},
|
||||
"Tags": [],
|
||||
"DkimAttributes": {
|
||||
"Status": "NOT_STARTED",
|
||||
"SigningEnabled": False,
|
||||
"SigningAttributesOrigin": "AWS_SES",
|
||||
},
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
def mock_make_api_call_dkim_fail_failed(self, operation_name, kwarg):
|
||||
if operation_name == "ListEmailIdentities":
|
||||
return {
|
||||
"EmailIdentities": [
|
||||
{
|
||||
"IdentityType": "DOMAIN",
|
||||
"IdentityName": "test-domain-dkim-failed",
|
||||
}
|
||||
],
|
||||
}
|
||||
elif operation_name == "GetEmailIdentity":
|
||||
return {
|
||||
"Policies": {},
|
||||
"Tags": [],
|
||||
"DkimAttributes": {
|
||||
"Status": "FAILED",
|
||||
"SigningEnabled": False,
|
||||
"SigningAttributesOrigin": "AWS_SES",
|
||||
},
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
def mock_make_api_call_dkim_pending(self, operation_name, kwarg):
|
||||
if operation_name == "ListEmailIdentities":
|
||||
return {
|
||||
"EmailIdentities": [
|
||||
{
|
||||
"IdentityType": "DOMAIN",
|
||||
"IdentityName": "test-domain-dkim-pending",
|
||||
}
|
||||
],
|
||||
}
|
||||
elif operation_name == "GetEmailIdentity":
|
||||
return {
|
||||
"Policies": {},
|
||||
"Tags": [],
|
||||
"DkimAttributes": {
|
||||
"Status": "PENDING",
|
||||
"SigningEnabled": False,
|
||||
"SigningAttributesOrigin": "AWS_SES",
|
||||
},
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
def mock_make_api_call_dkim_success_not_enabled(self, operation_name, kwarg):
|
||||
if operation_name == "ListEmailIdentities":
|
||||
return {
|
||||
"EmailIdentities": [
|
||||
{
|
||||
"IdentityType": "DOMAIN",
|
||||
"IdentityName": "test-domain-dkim-verified-not-signed",
|
||||
}
|
||||
],
|
||||
}
|
||||
elif operation_name == "GetEmailIdentity":
|
||||
return {
|
||||
"Policies": {},
|
||||
"Tags": [],
|
||||
"DkimAttributes": {
|
||||
"Status": "SUCCESS",
|
||||
"SigningEnabled": False,
|
||||
"SigningAttributesOrigin": "AWS_SES",
|
||||
},
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
class Test_ses_identity_dkim_enabled:
|
||||
@mock_aws
|
||||
def test_no_identities(self):
|
||||
client("sesv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled.ses_client",
|
||||
new=SES(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled import (
|
||||
ses_identity_dkim_enabled,
|
||||
)
|
||||
|
||||
check = ses_identity_dkim_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_dkim_pass,
|
||||
)
|
||||
def test_identity_dkim_enabled_and_verified(self):
|
||||
client("sesv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled.ses_client",
|
||||
new=SES(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled import (
|
||||
ses_identity_dkim_enabled,
|
||||
)
|
||||
|
||||
check = ses_identity_dkim_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "SES identity test-domain-dkim-pass has DKIM signing enabled and verified."
|
||||
)
|
||||
assert result[0].resource_id == "test-domain-dkim-pass"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:aws:ses:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:identity/test-domain-dkim-pass"
|
||||
)
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
@mock_aws
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_dkim_fail_not_started,
|
||||
)
|
||||
def test_identity_dkim_not_started(self):
|
||||
client("sesv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled.ses_client",
|
||||
new=SES(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled import (
|
||||
ses_identity_dkim_enabled,
|
||||
)
|
||||
|
||||
check = ses_identity_dkim_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "SES identity test-domain-dkim-not-started has DKIM signing not verified (status: NOT_STARTED)."
|
||||
)
|
||||
assert result[0].resource_id == "test-domain-dkim-not-started"
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
@mock_aws
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_dkim_fail_failed,
|
||||
)
|
||||
def test_identity_dkim_failed(self):
|
||||
client("sesv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled.ses_client",
|
||||
new=SES(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled import (
|
||||
ses_identity_dkim_enabled,
|
||||
)
|
||||
|
||||
check = ses_identity_dkim_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "SES identity test-domain-dkim-failed has DKIM signing failed verification."
|
||||
)
|
||||
assert result[0].resource_id == "test-domain-dkim-failed"
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
@mock_aws
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_dkim_pending,
|
||||
)
|
||||
def test_identity_dkim_pending(self):
|
||||
client("sesv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled.ses_client",
|
||||
new=SES(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled import (
|
||||
ses_identity_dkim_enabled,
|
||||
)
|
||||
|
||||
check = ses_identity_dkim_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "SES identity test-domain-dkim-pending has DKIM signing not verified (status: PENDING)."
|
||||
)
|
||||
assert result[0].resource_id == "test-domain-dkim-pending"
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
@mock_aws
|
||||
@mock.patch(
|
||||
"botocore.client.BaseClient._make_api_call",
|
||||
new=mock_make_api_call_dkim_success_not_enabled,
|
||||
)
|
||||
def test_identity_dkim_verified_but_not_enabled(self):
|
||||
client("sesv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled.ses_client",
|
||||
new=SES(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.ses.ses_identity_dkim_enabled.ses_identity_dkim_enabled import (
|
||||
ses_identity_dkim_enabled,
|
||||
)
|
||||
|
||||
check = ses_identity_dkim_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "SES identity test-domain-dkim-verified-not-signed has DKIM verified but signing is disabled."
|
||||
)
|
||||
assert result[0].resource_id == "test-domain-dkim-verified-not-signed"
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
@@ -29,6 +29,11 @@ def mock_make_api_call(self, operation_name, kwarg):
|
||||
"policy1": '{"policy1": "value1"}',
|
||||
},
|
||||
"Tags": {"tag1": "value1", "tag2": "value2"},
|
||||
"DkimAttributes": {
|
||||
"Status": "SUCCESS",
|
||||
"SigningEnabled": True,
|
||||
"SigningAttributesOrigin": "AWS_SES",
|
||||
},
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
@@ -78,3 +83,6 @@ class Test_SES_Service:
|
||||
assert ses.email_identities[arn].region == AWS_REGION_EU_WEST_1
|
||||
assert ses.email_identities[arn].policy == {"policy1": "value1"}
|
||||
assert ses.email_identities[arn].tags == {"tag1": "value1", "tag2": "value2"}
|
||||
assert ses.email_identities[arn].dkim_status == "SUCCESS"
|
||||
assert ses.email_identities[arn].dkim_signing_attributes_origin == "AWS_SES"
|
||||
assert ses.email_identities[arn].dkim_signing_enabled is True
|
||||
@@ -8,6 +8,7 @@ from prowler.providers.azure.models import AzureIdentityInfo, AzureRegionConfig
|
||||
|
||||
AZURE_SUBSCRIPTION_ID = str(uuid4())
|
||||
AZURE_SUBSCRIPTION_NAME = "Subscription Name"
|
||||
AZURE_SUBSCRIPTION_DISPLAY = f"{AZURE_SUBSCRIPTION_NAME} ({AZURE_SUBSCRIPTION_ID})"
|
||||
|
||||
# Azure Identity
|
||||
IDENTITY_ID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from unittest.mock import patch
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from azure.core.credentials import AccessToken
|
||||
from azure.core.exceptions import HttpResponseError
|
||||
from azure.identity import DefaultAzureCredential
|
||||
from mock import MagicMock
|
||||
|
||||
@@ -85,6 +87,7 @@ class TestAzureProvider:
|
||||
"python_latest_version": "3.12",
|
||||
"java_latest_version": "17",
|
||||
"recommended_minimal_tls_versions": ["1.2", "1.3"],
|
||||
"recommended_smb_channel_encryption_algorithms": ["AES-256-GCM"],
|
||||
"vm_backup_min_daily_retention_days": 7,
|
||||
"desired_vm_sku_sizes": [
|
||||
"Standard_A8_v2",
|
||||
@@ -432,8 +435,29 @@ class TestAzureProvider:
|
||||
)
|
||||
|
||||
def test_test_connection_with_ClientAuthenticationError(self):
|
||||
with pytest.raises(AzureHTTPResponseError) as exception:
|
||||
tenant_id = str(uuid4())
|
||||
tenant_id = str(uuid4())
|
||||
error_message = (
|
||||
"Authentication failed: Unable to get authority configuration for "
|
||||
f"https://login.microsoftonline.com/{tenant_id}."
|
||||
)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"prowler.providers.azure.azure_provider.AzureProvider.setup_session"
|
||||
) as mock_setup_session,
|
||||
patch(
|
||||
"prowler.providers.azure.azure_provider.SubscriptionClient"
|
||||
) as mock_subscription_client,
|
||||
pytest.raises(AzureHTTPResponseError) as exception,
|
||||
):
|
||||
mock_setup_session.return_value = MagicMock()
|
||||
mock_client = MagicMock()
|
||||
mock_client.subscriptions = MagicMock()
|
||||
mock_client.subscriptions.list.side_effect = HttpResponseError(
|
||||
message=error_message
|
||||
)
|
||||
mock_subscription_client.return_value = mock_client
|
||||
|
||||
AzureProvider.test_connection(
|
||||
browser_auth=True,
|
||||
tenant_id=tenant_id,
|
||||
@@ -441,9 +465,8 @@ class TestAzureProvider:
|
||||
)
|
||||
|
||||
assert exception.type == AzureHTTPResponseError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== f"[2010] Error in HTTP response from Azure - Authentication failed: Unable to get authority configuration for https://login.microsoftonline.com/{tenant_id}. Authority would typically be in a format of https://login.microsoftonline.com/your_tenant or https://tenant_name.ciamlogin.com or https://tenant_name.b2clogin.com/tenant.onmicrosoft.com/policy. Also please double check your tenant name or GUID is correct."
|
||||
assert exception.value.args[0] == (
|
||||
f"[2010] Error in HTTP response from Azure - {error_message}"
|
||||
)
|
||||
|
||||
def test_test_connection_without_any_method(self):
|
||||
@@ -527,3 +550,261 @@ class TestAzureProvider:
|
||||
regions = azure_provider.get_regions(subscription_ids=subscription_ids)
|
||||
|
||||
assert regions == expected_regions
|
||||
|
||||
|
||||
class TestAzureProviderSetupIdentitySubscriptions:
|
||||
"""Regression tests ensuring identity.subscriptions preserves every
|
||||
subscription even when multiple Azure subscriptions share the same
|
||||
display_name (which is permitted by Azure)."""
|
||||
|
||||
@staticmethod
|
||||
def _mock_subscription(display_name, subscription_id):
|
||||
mock_subscription = MagicMock()
|
||||
mock_subscription.display_name = display_name
|
||||
mock_subscription.subscription_id = subscription_id
|
||||
return mock_subscription
|
||||
|
||||
@staticmethod
|
||||
def _build_subscriptions_client_mock(list_result=None, get_map=None):
|
||||
"""Construct a fully explicit SubscriptionClient mock so the tests do
|
||||
not depend on MagicMock auto-attribute behavior, which makes the suite
|
||||
sensitive to shared state across test files."""
|
||||
subscriptions_operations = MagicMock()
|
||||
subscriptions_operations.list = MagicMock(return_value=list_result or [])
|
||||
if get_map is not None:
|
||||
subscriptions_operations.get = MagicMock(
|
||||
side_effect=lambda subscription_id: get_map[subscription_id]
|
||||
)
|
||||
else:
|
||||
subscriptions_operations.get = MagicMock()
|
||||
|
||||
tenants_operations = MagicMock()
|
||||
tenants_operations.list = MagicMock(return_value=[])
|
||||
|
||||
client_instance = MagicMock()
|
||||
client_instance.subscriptions = subscriptions_operations
|
||||
client_instance.tenants = tenants_operations
|
||||
|
||||
client_class = MagicMock(return_value=client_instance)
|
||||
return client_class
|
||||
|
||||
@staticmethod
|
||||
def _build_provider():
|
||||
"""Create an AzureProvider instance ready to invoke setup_identity
|
||||
with auth flags left False so the AAD lookup branches are skipped and
|
||||
the test focuses on the subscription resolution logic."""
|
||||
with patch.object(AzureProvider, "__init__", return_value=None):
|
||||
azure_provider = AzureProvider()
|
||||
azure_provider._session = MagicMock()
|
||||
azure_provider._region_config = AzureRegionConfig(
|
||||
name="AzureCloud",
|
||||
authority=None,
|
||||
base_url="https://management.azure.com",
|
||||
credential_scopes=["https://management.azure.com/.default"],
|
||||
)
|
||||
return azure_provider
|
||||
|
||||
def test_setup_identity_auto_discovery_preserves_unique_display_names(self):
|
||||
first_id = str(uuid4())
|
||||
second_id = str(uuid4())
|
||||
client_class = self._build_subscriptions_client_mock(
|
||||
list_result=[
|
||||
self._mock_subscription("Unique Name One", first_id),
|
||||
self._mock_subscription("Unique Name Two", second_id),
|
||||
]
|
||||
)
|
||||
with patch(
|
||||
"prowler.providers.azure.azure_provider.SubscriptionClient",
|
||||
client_class,
|
||||
):
|
||||
azure_provider = self._build_provider()
|
||||
|
||||
identity = azure_provider.setup_identity(
|
||||
az_cli_auth=False,
|
||||
sp_env_auth=False,
|
||||
browser_auth=False,
|
||||
managed_identity_auth=False,
|
||||
subscription_ids=[],
|
||||
client_id=None,
|
||||
)
|
||||
|
||||
assert identity.subscriptions == {
|
||||
first_id: "Unique Name One",
|
||||
second_id: "Unique Name Two",
|
||||
}
|
||||
|
||||
def test_setup_identity_auto_discovery_preserves_duplicate_display_names(
|
||||
self,
|
||||
):
|
||||
shared_name = "Shared Display Name"
|
||||
first_id = str(uuid4())
|
||||
second_id = str(uuid4())
|
||||
client_class = self._build_subscriptions_client_mock(
|
||||
list_result=[
|
||||
self._mock_subscription(shared_name, first_id),
|
||||
self._mock_subscription(shared_name, second_id),
|
||||
]
|
||||
)
|
||||
with patch(
|
||||
"prowler.providers.azure.azure_provider.SubscriptionClient",
|
||||
client_class,
|
||||
):
|
||||
azure_provider = self._build_provider()
|
||||
|
||||
identity = azure_provider.setup_identity(
|
||||
az_cli_auth=False,
|
||||
sp_env_auth=False,
|
||||
browser_auth=False,
|
||||
managed_identity_auth=False,
|
||||
subscription_ids=[],
|
||||
client_id=None,
|
||||
)
|
||||
|
||||
assert identity.subscriptions == {
|
||||
first_id: shared_name,
|
||||
second_id: shared_name,
|
||||
}
|
||||
|
||||
def test_setup_identity_filtered_preserves_unique_display_names(self):
|
||||
first_id = str(uuid4())
|
||||
second_id = str(uuid4())
|
||||
client_class = self._build_subscriptions_client_mock(
|
||||
get_map={
|
||||
first_id: self._mock_subscription("Unique Name One", first_id),
|
||||
second_id: self._mock_subscription("Unique Name Two", second_id),
|
||||
}
|
||||
)
|
||||
with patch(
|
||||
"prowler.providers.azure.azure_provider.SubscriptionClient",
|
||||
client_class,
|
||||
):
|
||||
azure_provider = self._build_provider()
|
||||
|
||||
identity = azure_provider.setup_identity(
|
||||
az_cli_auth=False,
|
||||
sp_env_auth=False,
|
||||
browser_auth=False,
|
||||
managed_identity_auth=False,
|
||||
subscription_ids=[first_id, second_id],
|
||||
client_id=None,
|
||||
)
|
||||
|
||||
assert identity.subscriptions == {
|
||||
first_id: "Unique Name One",
|
||||
second_id: "Unique Name Two",
|
||||
}
|
||||
|
||||
def test_setup_identity_filtered_preserves_duplicate_display_names(self):
|
||||
shared_name = "Shared Display Name"
|
||||
first_id = str(uuid4())
|
||||
second_id = str(uuid4())
|
||||
client_class = self._build_subscriptions_client_mock(
|
||||
get_map={
|
||||
first_id: self._mock_subscription(shared_name, first_id),
|
||||
second_id: self._mock_subscription(shared_name, second_id),
|
||||
}
|
||||
)
|
||||
with patch(
|
||||
"prowler.providers.azure.azure_provider.SubscriptionClient",
|
||||
client_class,
|
||||
):
|
||||
azure_provider = self._build_provider()
|
||||
|
||||
identity = azure_provider.setup_identity(
|
||||
az_cli_auth=False,
|
||||
sp_env_auth=False,
|
||||
browser_auth=False,
|
||||
managed_identity_auth=False,
|
||||
subscription_ids=[first_id, second_id],
|
||||
client_id=None,
|
||||
)
|
||||
|
||||
assert identity.subscriptions == {
|
||||
first_id: shared_name,
|
||||
second_id: shared_name,
|
||||
}
|
||||
|
||||
|
||||
class TestAzureProviderSetupIdentityEventLoop:
|
||||
"""Regression for the Celery worker scenario where
|
||||
asyncio.get_event_loop() raised "There is no current event loop in
|
||||
thread 'MainThread'." on Python 3.12. setup_identity now uses
|
||||
asyncio.run(), which creates its own loop and must work without a
|
||||
pre-existing one in the current thread."""
|
||||
|
||||
@staticmethod
|
||||
def _mock_subscription(display_name, subscription_id):
|
||||
mock_subscription = MagicMock()
|
||||
mock_subscription.display_name = display_name
|
||||
mock_subscription.subscription_id = subscription_id
|
||||
return mock_subscription
|
||||
|
||||
@staticmethod
|
||||
def _build_subscriptions_client_mock(subscriptions):
|
||||
subscriptions_operations = MagicMock()
|
||||
subscriptions_operations.list = MagicMock(return_value=subscriptions)
|
||||
subscriptions_operations.get = MagicMock()
|
||||
|
||||
tenants_operations = MagicMock()
|
||||
tenants_operations.list = MagicMock(return_value=[])
|
||||
|
||||
client_instance = MagicMock()
|
||||
client_instance.subscriptions = subscriptions_operations
|
||||
client_instance.tenants = tenants_operations
|
||||
return MagicMock(return_value=client_instance)
|
||||
|
||||
@staticmethod
|
||||
def _build_provider():
|
||||
with patch.object(AzureProvider, "__init__", return_value=None):
|
||||
azure_provider = AzureProvider()
|
||||
azure_provider._session = MagicMock()
|
||||
azure_provider._region_config = AzureRegionConfig(
|
||||
name="AzureCloud",
|
||||
authority=None,
|
||||
base_url="https://management.azure.com",
|
||||
credential_scopes=["https://management.azure.com/.default"],
|
||||
)
|
||||
return azure_provider
|
||||
|
||||
def test_setup_identity_succeeds_without_active_event_loop(self):
|
||||
sub_id = str(uuid4())
|
||||
subscriptions_client = self._build_subscriptions_client_mock(
|
||||
[self._mock_subscription("Sub", sub_id)]
|
||||
)
|
||||
|
||||
graph_client = MagicMock()
|
||||
graph_client.domains.get = AsyncMock(return_value=MagicMock(value=[]))
|
||||
graph_client.me.get = AsyncMock(return_value=None)
|
||||
|
||||
# Simulate the Celery worker state: no event loop registered for the
|
||||
# current thread. Before the fix this combination triggered
|
||||
# `RuntimeError: There is no current event loop in thread 'MainThread'.`
|
||||
# on Python 3.12 from asyncio.get_event_loop().
|
||||
asyncio.set_event_loop(None)
|
||||
try:
|
||||
with (
|
||||
patch(
|
||||
"prowler.providers.azure.azure_provider.GraphServiceClient",
|
||||
return_value=graph_client,
|
||||
),
|
||||
patch(
|
||||
"prowler.providers.azure.azure_provider.SubscriptionClient",
|
||||
subscriptions_client,
|
||||
),
|
||||
):
|
||||
azure_provider = self._build_provider()
|
||||
identity = azure_provider.setup_identity(
|
||||
az_cli_auth=False,
|
||||
sp_env_auth=True,
|
||||
browser_auth=False,
|
||||
managed_identity_auth=False,
|
||||
subscription_ids=[],
|
||||
client_id="00000000-0000-0000-0000-000000000000",
|
||||
)
|
||||
finally:
|
||||
# Re-arm a loop for sibling tests that may rely on the default.
|
||||
asyncio.set_event_loop(asyncio.new_event_loop())
|
||||
|
||||
assert isinstance(identity, AzureIdentityInfo)
|
||||
assert identity.subscriptions == {sub_id: "Sub"}
|
||||
graph_client.domains.get.assert_awaited_once()
|
||||
@@ -64,10 +64,12 @@ class TestAzureMutelist:
|
||||
finding.status = "FAIL"
|
||||
finding.resource_name = "test_resource"
|
||||
finding.resource_tags = {}
|
||||
finding.subscription = "subscription_1"
|
||||
finding.subscription = "12345678-1234-1234-1234-123456789012"
|
||||
|
||||
assert mutelist.is_finding_muted(
|
||||
finding, "12345678-1234-1234-1234-123456789012"
|
||||
finding,
|
||||
"12345678-1234-1234-1234-123456789012",
|
||||
"subscription_1",
|
||||
)
|
||||
|
||||
def test_is_finding_muted_subscription_id(self):
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.aisearch.aisearch_service import AISearchService
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_AISearch_service_not_publicly_accessible:
|
||||
def test_aisearch_sevice_no_aisearch_services(self):
|
||||
aisearch_client = mock.MagicMock
|
||||
aisearch_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aisearch_client.aisearch_services = {}
|
||||
|
||||
with (
|
||||
@@ -35,6 +38,7 @@ class Test_AISearch_service_not_publicly_accessible:
|
||||
aisearch_service_id = str(uuid4())
|
||||
aisearch_service_name = "Test AISearch Service"
|
||||
aisearch_client = mock.MagicMock
|
||||
aisearch_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aisearch_client.aisearch_services = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
aisearch_service_id: AISearchService(
|
||||
@@ -66,7 +70,7 @@ class Test_AISearch_service_not_publicly_accessible:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"AISearch Service {aisearch_service_name} from subscription {AZURE_SUBSCRIPTION_ID} allows public access."
|
||||
== f"AISearch Service {aisearch_service_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} allows public access."
|
||||
)
|
||||
assert result[0].resource_id == aisearch_service_id
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
@@ -77,6 +81,7 @@ class Test_AISearch_service_not_publicly_accessible:
|
||||
aisearch_service_id = str(uuid4())
|
||||
aisearch_service_name = "Test Search Service"
|
||||
aisearch_client = mock.MagicMock
|
||||
aisearch_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aisearch_client.aisearch_services = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
aisearch_service_id: AISearchService(
|
||||
@@ -108,7 +113,7 @@ class Test_AISearch_service_not_publicly_accessible:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"AISearch Service {aisearch_service_name} from subscription {AZURE_SUBSCRIPTION_ID} does not allows public access."
|
||||
== f"AISearch Service {aisearch_service_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not allows public access."
|
||||
)
|
||||
assert result[0].resource_id == aisearch_service_id
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
|
||||
+8
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.aks.aks_service import Cluster
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_aks_cluster_rbac_enabled:
|
||||
def test_aks_no_subscriptions(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_aks_cluster_rbac_enabled:
|
||||
|
||||
def test_aks_subscription_empty(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_aks_cluster_rbac_enabled:
|
||||
|
||||
def test_aks_cluster_rbac_enabled(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -91,7 +96,7 @@ class Test_aks_cluster_rbac_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"RBAC is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"RBAC is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
assert result[0].resource_id == cluster_id
|
||||
@@ -100,6 +105,7 @@ class Test_aks_cluster_rbac_enabled:
|
||||
|
||||
def test_aks_rbac_not_enabled(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -136,7 +142,7 @@ class Test_aks_cluster_rbac_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"RBAC is not enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"RBAC is not enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
assert result[0].resource_id == cluster_id
|
||||
|
||||
+10
-3
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.aks.aks_service import Cluster
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_aks_clusters_created_with_private_nodes:
|
||||
def test_aks_no_subscriptions(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
|
||||
def test_aks_subscription_empty(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
|
||||
def test_aks_cluster_no_private_nodes(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -91,7 +96,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Cluster 'cluster_name' was not created with private nodes in subscription '{AZURE_SUBSCRIPTION_ID}'"
|
||||
== f"Cluster 'cluster_name' was not created with private nodes in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'"
|
||||
)
|
||||
assert result[0].resource_id == cluster_id
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
@@ -100,6 +105,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
|
||||
def test_aks_cluster_private_nodes(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -136,7 +142,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Cluster 'cluster_name' was created with private nodes in subscription '{AZURE_SUBSCRIPTION_ID}'"
|
||||
== f"Cluster 'cluster_name' was created with private nodes in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'"
|
||||
)
|
||||
assert result[0].resource_id == cluster_id
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
@@ -145,6 +151,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
|
||||
def test_aks_cluster_public_and_private_nodes(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -185,7 +192,7 @@ class Test_aks_clusters_created_with_private_nodes:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Cluster 'cluster_name' was not created with private nodes in subscription '{AZURE_SUBSCRIPTION_ID}'"
|
||||
== f"Cluster 'cluster_name' was not created with private nodes in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'"
|
||||
)
|
||||
assert result[0].resource_id == cluster_id
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
|
||||
+10
-3
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.aks.aks_service import Cluster
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_aks_clusters_public_access_disabled:
|
||||
def test_aks_no_subscriptions(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
|
||||
def test_aks_subscription_empty(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
|
||||
def test_aks_cluster_public_fqdn(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -91,7 +96,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Public access to nodes is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'"
|
||||
== f"Public access to nodes is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'"
|
||||
)
|
||||
assert result[0].resource_id == cluster_id
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
@@ -100,6 +105,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
|
||||
def test_aks_cluster_private_fqdn(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -136,7 +142,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Public access to nodes is disabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'"
|
||||
== f"Public access to nodes is disabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'"
|
||||
)
|
||||
assert result[0].resource_id == cluster_id
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
@@ -145,6 +151,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
|
||||
def test_aks_cluster_private_fqdn_with_public_ip(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -181,7 +188,7 @@ class Test_aks_clusters_public_access_disabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Public access to nodes is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'"
|
||||
== f"Public access to nodes is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'"
|
||||
)
|
||||
assert result[0].resource_id == cluster_id
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
|
||||
+8
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.aks.aks_service import Cluster
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_aks_network_policy_enabled:
|
||||
def test_aks_no_subscriptions(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_aks_network_policy_enabled:
|
||||
|
||||
def test_aks_subscription_empty(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
aks_client.clusters = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_aks_network_policy_enabled:
|
||||
|
||||
def test_aks_network_policy_enabled(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -91,7 +96,7 @@ class Test_aks_network_policy_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Network policy is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Network policy is enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
assert result[0].resource_id == cluster_id
|
||||
@@ -100,6 +105,7 @@ class Test_aks_network_policy_enabled:
|
||||
|
||||
def test_aks_network_policy_disabled(self):
|
||||
aks_client = mock.MagicMock
|
||||
aks_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cluster_id = str(uuid4())
|
||||
aks_client.clusters = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -136,7 +142,7 @@ class Test_aks_network_policy_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Network policy is not enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Network policy is not enabled for cluster 'cluster_name' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "cluster_name"
|
||||
assert result[0].resource_id == cluster_id
|
||||
|
||||
@@ -8,6 +8,7 @@ from azure.monitor.query import LogsQueryResult
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -193,6 +194,9 @@ class Test_APIM_Service(TestCase):
|
||||
|
||||
# Properly mock the nested client structure
|
||||
mock_client = mock.MagicMock()
|
||||
mock_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
mock_workspaces = mock.MagicMock()
|
||||
mock_workspaces.get.return_value = mock_workspace
|
||||
mock_client.workspaces = mock_workspaces
|
||||
@@ -246,6 +250,9 @@ class Test_APIM_Service(TestCase):
|
||||
|
||||
# Properly mock the nested client structure
|
||||
mock_client = mock.MagicMock()
|
||||
mock_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
mock_client.query_workspace.return_value = mock_response
|
||||
mock_logsquery_client.clients = {AZURE_SUBSCRIPTION_ID: mock_client}
|
||||
|
||||
|
||||
+106
-4
@@ -2,7 +2,9 @@ from datetime import datetime
|
||||
from unittest import mock
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -139,10 +141,18 @@ def mock_get_llm_operations_logs_no_workspace(subscription, instance, minutes):
|
||||
return []
|
||||
|
||||
|
||||
def mock_get_llm_operations_logs_by_subscription(subscription, instance, minutes):
|
||||
"""Return different logs per subscription to validate isolation."""
|
||||
if subscription == AZURE_SUBSCRIPTION_ID:
|
||||
return mock_get_llm_operations_logs_attacker(subscription, instance, minutes)
|
||||
return mock_get_llm_operations_logs_2_operations(subscription, instance, minutes)
|
||||
|
||||
|
||||
class Test_apim_threat_detection_llm_jacking:
|
||||
def test_no_apim_instances(self):
|
||||
"""Test when there are no APIM instances"""
|
||||
apim_client = mock.MagicMock()
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.instances = {}
|
||||
apim_client.audit_config = {
|
||||
"apim_threat_detection_llm_jacking_threshold": 0.1,
|
||||
@@ -175,6 +185,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
def test_no_potential_llm_jacking(self):
|
||||
"""Test when no potential LLM jacking is detected"""
|
||||
apim_client = mock.MagicMock()
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.instances = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
mock.MagicMock(
|
||||
@@ -184,7 +195,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
)
|
||||
]
|
||||
}
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID}
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.audit_config = {
|
||||
"apim_threat_detection_llm_jacking_threshold": 0.9,
|
||||
"apim_threat_detection_llm_jacking_minutes": 1440,
|
||||
@@ -240,6 +251,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
def test_potential_llm_jacking_detected(self):
|
||||
"""Test when potential LLM jacking is detected"""
|
||||
apim_client = mock.MagicMock()
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.instances = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
mock.MagicMock(
|
||||
@@ -286,6 +298,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
"Potential LLM Jacking attack detected from IP address 10.0.0.50"
|
||||
in result[0].status_extended
|
||||
)
|
||||
assert AZURE_SUBSCRIPTION_DISPLAY in result[0].status_extended
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource["name"] == "10.0.0.50"
|
||||
assert result[0].resource["id"] == "10.0.0.50"
|
||||
@@ -293,6 +306,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
def test_higher_threshold_no_detection(self):
|
||||
"""Test when threshold is higher and no attack is detected"""
|
||||
apim_client = mock.MagicMock()
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.instances = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
mock.MagicMock(
|
||||
@@ -302,7 +316,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
)
|
||||
]
|
||||
}
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID}
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.audit_config = {
|
||||
"apim_threat_detection_llm_jacking_threshold": 0.9,
|
||||
"apim_threat_detection_llm_jacking_minutes": 1440,
|
||||
@@ -367,7 +381,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
)
|
||||
]
|
||||
}
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID}
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.audit_config = {
|
||||
"apim_threat_detection_llm_jacking_threshold": 0.9,
|
||||
"apim_threat_detection_llm_jacking_minutes": 1440,
|
||||
@@ -423,6 +437,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
def test_multiple_subscriptions(self):
|
||||
"""Test with multiple subscriptions"""
|
||||
apim_client = mock.MagicMock()
|
||||
apim_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
apim_client.instances = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
mock.MagicMock(
|
||||
@@ -440,7 +455,7 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
],
|
||||
}
|
||||
apim_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME,
|
||||
"another-subscription": "another-subscription-id",
|
||||
}
|
||||
apim_client.audit_config = {
|
||||
@@ -496,3 +511,90 @@ class Test_apim_threat_detection_llm_jacking:
|
||||
"No potential LLM Jacking attacks detected"
|
||||
in report.status_extended
|
||||
)
|
||||
|
||||
def test_multiple_subscriptions_keep_findings_isolated(self):
|
||||
"""Ensure findings from one subscription do not leak into another."""
|
||||
apim_client = mock.MagicMock()
|
||||
second_subscription_id = "another-subscription"
|
||||
second_subscription_name = "another-subscription-id"
|
||||
apim_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME,
|
||||
second_subscription_id: second_subscription_name,
|
||||
}
|
||||
apim_client.instances = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
mock.MagicMock(
|
||||
id="/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim",
|
||||
name="test-apim",
|
||||
log_analytics_workspace_id="/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/test-workspace",
|
||||
)
|
||||
],
|
||||
second_subscription_id: [
|
||||
mock.MagicMock(
|
||||
id="/subscriptions/another-sub/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/another-apim",
|
||||
name="another-apim",
|
||||
log_analytics_workspace_id="/subscriptions/another-sub/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/another-workspace",
|
||||
)
|
||||
],
|
||||
}
|
||||
apim_client.audit_config = {
|
||||
"apim_threat_detection_llm_jacking_threshold": 0.2,
|
||||
"apim_threat_detection_llm_jacking_minutes": 1440,
|
||||
"apim_threat_detection_llm_jacking_actions": [
|
||||
"ChatCompletions_Create",
|
||||
"ImageGenerations_Create",
|
||||
"Completions_Create",
|
||||
"Embeddings_Create",
|
||||
"FineTuning_Jobs_Create",
|
||||
"Models_List",
|
||||
"Deployments_List",
|
||||
"Deployments_Get",
|
||||
"Deployments_Create",
|
||||
"Deployments_Delete",
|
||||
"Messages_Create",
|
||||
"Claude_Create",
|
||||
"GenerateContent",
|
||||
"GenerateText",
|
||||
"GenerateImage",
|
||||
"Llama_Create",
|
||||
"CodeLlama_Create",
|
||||
"Gemini_Generate",
|
||||
"Claude_Generate",
|
||||
"Llama_Generate",
|
||||
],
|
||||
}
|
||||
apim_client.get_llm_operations_logs = (
|
||||
mock_get_llm_operations_logs_by_subscription
|
||||
)
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.apim.apim_threat_detection_llm_jacking.apim_threat_detection_llm_jacking.apim_client",
|
||||
new=apim_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.apim.apim_threat_detection_llm_jacking.apim_threat_detection_llm_jacking import (
|
||||
apim_threat_detection_llm_jacking,
|
||||
)
|
||||
|
||||
check = apim_threat_detection_llm_jacking()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
report_by_subscription = {report.subscription: report for report in result}
|
||||
|
||||
assert report_by_subscription[AZURE_SUBSCRIPTION_ID].status == "FAIL"
|
||||
assert (
|
||||
AZURE_SUBSCRIPTION_DISPLAY
|
||||
in report_by_subscription[AZURE_SUBSCRIPTION_ID].status_extended
|
||||
)
|
||||
assert report_by_subscription[second_subscription_id].status == "PASS"
|
||||
assert (
|
||||
f"{second_subscription_name} ({second_subscription_id})"
|
||||
in report_by_subscription[second_subscription_id].status_extended
|
||||
)
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_client_certificates_on:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_client_certificates_on:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_client_certificates_on:
|
||||
def test_app_client_certificates_on(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_client_certificates_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Clients are required to present a certificate for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Clients are required to present a certificate for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -101,6 +106,7 @@ class Test_app_client_certificates_on:
|
||||
def test_app_client_certificates_off(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_client_certificates_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Clients are not required to present a certificate for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Clients are not required to present a certificate for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ensure_auth_is_set_up:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ensure_auth_is_set_up:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ensure_auth_is_set_up:
|
||||
def test_app_auth_enabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_ensure_auth_is_set_up:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Authentication is set up for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Authentication is set up for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -101,6 +106,7 @@ class Test_app_ensure_auth_is_set_up:
|
||||
def test_app_auth_disabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_ensure_auth_is_set_up:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Authentication is not set up for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Authentication is not set up for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ensure_http_is_redirected_to_https:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ensure_http_is_redirected_to_https:
|
||||
|
||||
def test_app_subscriptions_empty_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ensure_http_is_redirected_to_https:
|
||||
def test_app_http_to_https(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_ensure_http_is_redirected_to_https:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"HTTP is not redirected to HTTPS for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"HTTP is not redirected to HTTPS for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -101,6 +106,7 @@ class Test_app_ensure_http_is_redirected_to_https:
|
||||
def test_app_http_to_https_enabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_ensure_http_is_redirected_to_https:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"HTTP is redirected to HTTPS for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"HTTP is redirected to HTTPS for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
+14
-4
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
|
||||
def test_app_subscriptions_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_configurations_none(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -92,6 +97,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_linux_java_version_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"java_latest_version": "17"}
|
||||
|
||||
@@ -132,7 +138,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Java version is set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Java version is set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -142,6 +148,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_linux_java_version_not_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"java_latest_version": "17"}
|
||||
|
||||
@@ -182,7 +189,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Java version is set to 'Tomcat|9.0-java11', but should be set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Java version is set to 'Tomcat|9.0-java11', but should be set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -192,6 +199,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_windows_java_version_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"java_latest_version": "17"}
|
||||
|
||||
@@ -232,7 +240,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Java version is set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Java version is set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -242,6 +250,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_windows_java_version_not_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.audit_config = {"java_latest_version": "17"}
|
||||
|
||||
with (
|
||||
@@ -281,7 +290,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Java version is set to 'java11', but should be set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Java version is set to 'java11', but should be set to 'java 17' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -291,6 +300,7 @@ class Test_app_ensure_java_version_is_latest:
|
||||
def test_app_linux_php_version_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"java_latest_version": "17"}
|
||||
|
||||
|
||||
+9
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ensure_php_version_is_latest:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ensure_php_version_is_latest:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ensure_php_version_is_latest:
|
||||
def test_app_configurations_none(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -92,6 +97,7 @@ class Test_app_ensure_php_version_is_latest:
|
||||
def test_app_php_version_not_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"php_latest_version": "8.2"}
|
||||
|
||||
@@ -130,7 +136,7 @@ class Test_app_ensure_php_version_is_latest:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"PHP version is set to 'php|8.0', the latest version that you could use is the '8.2' version, for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"PHP version is set to 'php|8.0', the latest version that you could use is the '8.2' version, for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -140,6 +146,7 @@ class Test_app_ensure_php_version_is_latest:
|
||||
def test_app_php_version_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"php_latest_version": "8.2"}
|
||||
|
||||
@@ -178,7 +185,7 @@ class Test_app_ensure_php_version_is_latest:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"PHP version is set to '8.2' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"PHP version is set to '8.2' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+9
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ensure_python_version_is_latest:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ensure_python_version_is_latest:
|
||||
|
||||
def test_app_subscriptions_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ensure_python_version_is_latest:
|
||||
def test_app_configurations_none(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
@@ -91,6 +96,7 @@ class Test_app_ensure_python_version_is_latest:
|
||||
def test_app_python_version_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"python_latest_version": "3.12"}
|
||||
|
||||
@@ -129,7 +135,7 @@ class Test_app_ensure_python_version_is_latest:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Python version is set to '3.12' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Python version is set to '3.12' for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -139,6 +145,7 @@ class Test_app_ensure_python_version_is_latest:
|
||||
def test_app_python_version_not_latest(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
app_client.audit_config = {"python_latest_version": "3.12"}
|
||||
|
||||
@@ -177,7 +184,7 @@ class Test_app_ensure_python_version_is_latest:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Python version is 'python|3.10', the latest version that you could use is the '3.12' version, for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Python version is 'python|3.10', the latest version that you could use is the '3.12' version, for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+10
-3
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ensure_using_http20:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ensure_using_http20:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ensure_using_http20:
|
||||
def test_app_configurations_none(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_ensure_using_http20:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"HTTP/2.0 is not enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"HTTP/2.0 is not enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -101,6 +106,7 @@ class Test_app_ensure_using_http20:
|
||||
def test_app_http20_enabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_ensure_using_http20:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"HTTP/2.0 is enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"HTTP/2.0 is enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -147,6 +153,7 @@ class Test_app_ensure_using_http20:
|
||||
def test_app_http20_not_enabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -183,7 +190,7 @@ class Test_app_ensure_using_http20:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"HTTP/2.0 is not enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"HTTP/2.0 is not enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+10
-3
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_ftp_deployment_disabled:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
|
||||
def test_app_subscriptions_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
def test_app_configurations_none(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"FTP is enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"FTP is enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -101,6 +106,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
def test_app_ftp_deployment_disabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"FTP is enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"FTP is enabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -147,6 +153,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
def test_app_ftp_deploy_enabled(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -183,7 +190,7 @@ class Test_app_ftp_deployment_disabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"FTP is disabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"FTP is disabled for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_access_keys_configured:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_access_keys_configured:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.functions = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_function_access_keys_configured:
|
||||
|
||||
def test_app_function_no_keys(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.functions = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -98,7 +103,7 @@ class Test_app_function_access_keys_configured:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 does not have function keys configured."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have function keys configured."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
@@ -107,6 +112,7 @@ class Test_app_function_access_keys_configured:
|
||||
|
||||
def test_app_function_using_functions_keys(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.functions = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -153,7 +159,7 @@ class Test_app_function_access_keys_configured:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has function keys configured."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has function keys configured."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
|
||||
+12
-4
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_application_insights_enabled:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_application_insights_enabled:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -56,6 +60,7 @@ class Test_app_function_application_insights_enabled:
|
||||
|
||||
def test_app_function_no_app_insights(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -97,7 +102,7 @@ class Test_app_function_application_insights_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 is not using Application Insights."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not using Application Insights."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
@@ -106,6 +111,7 @@ class Test_app_function_application_insights_enabled:
|
||||
|
||||
def test_app_function_using_app_insights(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -147,7 +153,7 @@ class Test_app_function_application_insights_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 is using Application Insights."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is using Application Insights."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
@@ -156,6 +162,7 @@ class Test_app_function_application_insights_enabled:
|
||||
|
||||
def test_app_function_using_app_insights_different_key(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -197,7 +204,7 @@ class Test_app_function_application_insights_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 is using Application Insights."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is using Application Insights."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
@@ -206,6 +213,7 @@ class Test_app_function_application_insights_enabled:
|
||||
|
||||
def test_app_function_with_app_insights_no_key(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -247,7 +255,7 @@ class Test_app_function_application_insights_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 is not using Application Insights."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not using Application Insights."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
|
||||
+10
-3
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_ftps_deployment_disabled:
|
||||
def test_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
|
||||
def test_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -56,6 +60,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
|
||||
def test_function_ftp_deployment_enabled(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -97,7 +102,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has FTP deployment enabled"
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has FTP deployment enabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
@@ -106,6 +111,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
|
||||
def test_function_ftps_deployment_enabled(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -147,7 +153,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has FTPS deployment enabled"
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has FTPS deployment enabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
@@ -156,6 +162,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
|
||||
def test_function_ftp_and_ftps_deployment_disabled(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -197,7 +204,7 @@ class Test_app_function_ftps_deployment_disabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has FTP and FTPS deployment disabled"
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has FTP and FTPS deployment disabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_identity_is_configured:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_identity_is_configured:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -56,6 +60,7 @@ class Test_app_function_identity_is_configured:
|
||||
|
||||
def test_app_function_no_identity(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -97,7 +102,7 @@ class Test_app_function_identity_is_configured:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 does not have a managed identity enabled."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have a managed identity enabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
@@ -106,6 +111,7 @@ class Test_app_function_identity_is_configured:
|
||||
|
||||
def test_app_function_identity_configured(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -147,7 +153,7 @@ class Test_app_function_identity_is_configured:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has a SystemAssigned identity enabled."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has a SystemAssigned identity enabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
|
||||
+16
-7
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.config import USER_ACCESS_ADMINISTRATOR_ROLE_ID
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_identity_without_admin_privileges:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -34,6 +37,7 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -57,6 +61,7 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
|
||||
def test_app_function_no_identity(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -98,7 +103,9 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
|
||||
def test_app_function_no_admin_roles(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -175,7 +182,7 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has a managed identity enabled but without admin privileges."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has a managed identity enabled but without admin privileges."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
@@ -184,7 +191,9 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
|
||||
def test_app_function_admin_roles(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -212,7 +221,7 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
function_id = str(uuid4())
|
||||
function_scope = f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/resourceGroups/rg/providers/Microsoft.Web/sites/function1"
|
||||
app_client.functions = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
function_id: FunctionApp(
|
||||
id=function_id,
|
||||
name="function1",
|
||||
@@ -229,11 +238,11 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
}
|
||||
|
||||
iam_client.subscriptions = {
|
||||
"subscription-name-1": AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME,
|
||||
}
|
||||
|
||||
iam_client.role_assignments = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"role-assignment-id-2": RoleAssignment(
|
||||
id="role-assignment-id-2",
|
||||
name="role-assignment-name-2",
|
||||
@@ -246,7 +255,7 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
}
|
||||
|
||||
iam_client.roles = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{USER_ACCESS_ADMINISTRATOR_ROLE_ID}": Role(
|
||||
id=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{USER_ACCESS_ADMINISTRATOR_ROLE_ID}",
|
||||
name="User Access Administrator",
|
||||
@@ -263,9 +272,9 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has a managed identity enabled and it is configure with admin privileges using role User Access Administrator."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has a managed identity enabled and it is configure with admin privileges using role User Access Administrator."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].subscription == "subscription-name-1"
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].location == "West Europe"
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_latest_runtime_version:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_latest_runtime_version:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -56,6 +60,7 @@ class Test_app_function_latest_runtime_version:
|
||||
|
||||
def test_app_function_runtime_is_latest(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -96,7 +101,7 @@ class Test_app_function_latest_runtime_version:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
"Function function1 is using the latest runtime."
|
||||
f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is using the latest runtime."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
@@ -105,6 +110,7 @@ class Test_app_function_latest_runtime_version:
|
||||
|
||||
def test_app_function_runtime_is_not_latest(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -145,7 +151,7 @@ class Test_app_function_latest_runtime_version:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
"Function function1 is not using the latest runtime. The current runtime is '2' and should be '~4'."
|
||||
f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not using the latest runtime. The current runtime is '2' and should be '~4'."
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_not_publicly_accessible:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_not_publicly_accessible:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -56,6 +60,7 @@ class Test_app_function_not_publicly_accessible:
|
||||
|
||||
def test_app_function_not_publicly_accessible(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -97,7 +102,7 @@ class Test_app_function_not_publicly_accessible:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 is not publicly accessible."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not publicly accessible."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
@@ -106,6 +111,7 @@ class Test_app_function_not_publicly_accessible:
|
||||
|
||||
def test_app_function_publicly_accessible(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -147,7 +153,7 @@ class Test_app_function_not_publicly_accessible:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 is publicly accessible."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} is publicly accessible."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
|
||||
+10
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_function_vnet_integration_enabled:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -33,6 +36,7 @@ class Test_app_function_vnet_integration_enabled:
|
||||
|
||||
def test_app_subscription_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -56,6 +60,7 @@ class Test_app_function_vnet_integration_enabled:
|
||||
|
||||
def test_app_function_vnet_integration_enabled(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -97,14 +102,16 @@ class Test_app_function_vnet_integration_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 has Virtual Network integration enabled with subnet 'vnet_subnet_id' enabled."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} has Virtual Network integration enabled with subnet 'vnet_subnet_id' enabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].location == "West Europe"
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
|
||||
def test_app_function_vnet_integration_disabled(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -146,8 +153,9 @@ class Test_app_function_vnet_integration_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Function function1 does not have virtual network integration enabled."
|
||||
== f"Function function1 from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have virtual network integration enabled."
|
||||
)
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].location == "West Europe"
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
+12
-4
@@ -1,7 +1,9 @@
|
||||
from unittest import mock
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ class Test_app_http_logs_enabled:
|
||||
|
||||
def test_app_http_logs_enabled_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_app_http_logs_enabled:
|
||||
|
||||
def test_app_subscriptions_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_http_logs_enabled:
|
||||
|
||||
def test_no_diagnostics_settings(self):
|
||||
app_client = mock.MagicMock()
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
@@ -93,12 +98,13 @@ class Test_app_http_logs_enabled:
|
||||
assert result[0].resource_id == "resource_id"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"App app1 does not have a diagnostic setting in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"App app1 does not have a diagnostic setting in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
|
||||
def test_diagnostic_setting_configured(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -233,11 +239,12 @@ class Test_app_http_logs_enabled:
|
||||
assert result[0].resource_id == "resource_id2"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"App app_id-2 has HTTP Logs enabled in diagnostic setting name_diagnostic_setting2 in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
== f"App app_id-2 has HTTP Logs enabled in diagnostic setting name_diagnostic_setting2 in subscription {AZURE_SUBSCRIPTION_DISPLAY}"
|
||||
)
|
||||
|
||||
def test_diagnostic_setting_with_all_logs_category_group(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -296,11 +303,12 @@ class Test_app_http_logs_enabled:
|
||||
assert result[0].resource_id == "resource_id3"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"App app_id-3 has allLogs category group which includes HTTP Logs enabled in diagnostic setting name_diagnostic_setting3 in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
== f"App app_id-3 has allLogs category group which includes HTTP Logs enabled in diagnostic setting name_diagnostic_setting3 in subscription {AZURE_SUBSCRIPTION_DISPLAY}"
|
||||
)
|
||||
|
||||
def test_diagnostic_setting_with_all_logs_category_group_disabled(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -359,5 +367,5 @@ class Test_app_http_logs_enabled:
|
||||
assert result[0].resource_id == "resource_id4"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"App app_id-4 does not have HTTP Logs enabled in diagnostic setting name_diagnostic_setting4 in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
== f"App app_id-4 does not have HTTP Logs enabled in diagnostic setting name_diagnostic_setting4 in subscription {AZURE_SUBSCRIPTION_DISPLAY}"
|
||||
)
|
||||
+12
-4
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_minimum_tls_version_12:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_minimum_tls_version_12:
|
||||
|
||||
def test_app_subscriptions_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_minimum_tls_version_12:
|
||||
def test_app_none_configurations(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_minimum_tls_version_12:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Minimum TLS version is not set to 1.2 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Minimum TLS version is not set to 1.2 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -101,6 +106,7 @@ class Test_app_minimum_tls_version_12:
|
||||
def test_app_min_tls_version_12(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_minimum_tls_version_12:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Minimum TLS version is set to 1.2 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Minimum TLS version is set to 1.2 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -147,6 +153,7 @@ class Test_app_minimum_tls_version_12:
|
||||
def test_app_min_tls_version_10(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -183,7 +190,7 @@ class Test_app_minimum_tls_version_12:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Minimum TLS version is not set to 1.2 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Minimum TLS version is not set to 1.2 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -193,6 +200,7 @@ class Test_app_minimum_tls_version_12:
|
||||
def test_app_min_tls_version_13(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -229,7 +237,7 @@ class Test_app_minimum_tls_version_12:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Minimum TLS version is set to 1.3 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Minimum TLS version is set to 1.3 for app 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_app_register_with_identity:
|
||||
def test_app_no_subscriptions(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_app_register_with_identity:
|
||||
|
||||
def test_app_subscriptions_empty(self):
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
app_client.apps = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_app_register_with_identity:
|
||||
def test_app_none_configurations(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -91,7 +96,7 @@ class Test_app_register_with_identity:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"App 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}' does not have an identity configured."
|
||||
== f"App 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}' does not have an identity configured."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
@@ -101,6 +106,7 @@ class Test_app_register_with_identity:
|
||||
def test_app_identity(self):
|
||||
resource_id = f"/subscriptions/{uuid4()}"
|
||||
app_client = mock.MagicMock
|
||||
app_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -137,7 +143,7 @@ class Test_app_register_with_identity:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"App 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_ID}' has an identity configured."
|
||||
== f"App 'app_id-1' in subscription '{AZURE_SUBSCRIPTION_DISPLAY}' has an identity configured."
|
||||
)
|
||||
assert result[0].resource_id == resource_id
|
||||
assert result[0].resource_name == "app_id-1"
|
||||
|
||||
+9
-4
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
|
||||
from prowler.providers.azure.services.appinsights.appinsights_service import Component
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_appinsights_ensure_is_configured:
|
||||
def test_appinsights_no_subscriptions(self):
|
||||
appinsights_client = mock.MagicMock
|
||||
appinsights_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
appinsights_client.components = {}
|
||||
|
||||
with (
|
||||
@@ -34,7 +39,7 @@ class Test_appinsights_ensure_is_configured:
|
||||
appinsights_client = mock.MagicMock
|
||||
appinsights_client.components = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
appinsights_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -60,7 +65,7 @@ class Test_appinsights_ensure_is_configured:
|
||||
assert result[0].resource_name == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There are no AppInsight configured in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"There are no AppInsight configured in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
|
||||
def test_appinsights_configured(self):
|
||||
@@ -76,7 +81,7 @@ class Test_appinsights_ensure_is_configured:
|
||||
}
|
||||
}
|
||||
appinsights_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -103,5 +108,5 @@ class Test_appinsights_ensure_is_configured:
|
||||
assert result[0].location == "global"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is at least one AppInsight configured in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"There is at least one AppInsight configured in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
+13
-2
@@ -3,7 +3,9 @@ from unittest.mock import MagicMock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class TestContainerRegistryAdminUserDisabled:
|
||||
def test_no_container_registries(self):
|
||||
containerregistry_client = MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
containerregistry_client.registries = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +38,9 @@ class TestContainerRegistryAdminUserDisabled:
|
||||
|
||||
def test_container_registry_admin_user_enabled(self):
|
||||
containerregistry_client = MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
registry_id = str(uuid4())
|
||||
|
||||
with (
|
||||
@@ -76,7 +84,7 @@ class TestContainerRegistryAdminUserDisabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_ID} has its admin user enabled."
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_DISPLAY} has its admin user enabled."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "mock_registry"
|
||||
@@ -90,6 +98,9 @@ class TestContainerRegistryAdminUserDisabled:
|
||||
|
||||
def test_container_registry_admin_user_disabled(self):
|
||||
containerregistry_client = mock.MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
containerregistry_client.registries = {}
|
||||
|
||||
with (
|
||||
@@ -135,7 +146,7 @@ class TestContainerRegistryAdminUserDisabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_ID} has its admin user disabled."
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_DISPLAY} has its admin user disabled."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "mock_registry"
|
||||
|
||||
+13
-2
@@ -3,7 +3,9 @@ from unittest.mock import MagicMock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_containerregistry_not_publicly_accessible:
|
||||
def test_no_container_registries(self):
|
||||
containerregistry_client = MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
containerregistry_client.registries = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +38,9 @@ class Test_containerregistry_not_publicly_accessible:
|
||||
|
||||
def test_container_registry_network_access_unrestricted(self):
|
||||
containerregistry_client = MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
registry_id = str(uuid4())
|
||||
|
||||
with (
|
||||
@@ -93,7 +101,7 @@ class Test_containerregistry_not_publicly_accessible:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Container Registry {containerregistry_client.registries[AZURE_SUBSCRIPTION_ID][registry_id].name} from subscription {AZURE_SUBSCRIPTION_ID} allows unrestricted network access."
|
||||
== f"Container Registry {containerregistry_client.registries[AZURE_SUBSCRIPTION_ID][registry_id].name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} allows unrestricted network access."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "mock_registry"
|
||||
@@ -107,6 +115,9 @@ class Test_containerregistry_not_publicly_accessible:
|
||||
|
||||
def test_container_registry_network_access_restricted(self):
|
||||
containerregistry_client = mock.MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
containerregistry_client.registries = {}
|
||||
|
||||
with (
|
||||
@@ -168,7 +179,7 @@ class Test_containerregistry_not_publicly_accessible:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Container Registry {containerregistry_client.registries[AZURE_SUBSCRIPTION_ID][registry_id].name} from subscription {AZURE_SUBSCRIPTION_ID} does not allow unrestricted network access."
|
||||
== f"Container Registry {containerregistry_client.registries[AZURE_SUBSCRIPTION_ID][registry_id].name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not allow unrestricted network access."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "mock_registry"
|
||||
|
||||
+13
-2
@@ -3,7 +3,9 @@ from unittest.mock import MagicMock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_containerregistry_uses_private_link:
|
||||
def test_no_container_registries(self):
|
||||
containerregistry_client = MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
containerregistry_client.registries = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +38,9 @@ class Test_containerregistry_uses_private_link:
|
||||
|
||||
def test_container_registry_not_uses_private_link(self):
|
||||
containerregistry_client = MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
registry_id = str(uuid4())
|
||||
|
||||
with (
|
||||
@@ -76,7 +84,7 @@ class Test_containerregistry_uses_private_link:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_ID} does not use a private link."
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not use a private link."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "mock_registry"
|
||||
@@ -90,6 +98,9 @@ class Test_containerregistry_uses_private_link:
|
||||
|
||||
def test_container_registry_uses_private_link(self):
|
||||
containerregistry_client = mock.MagicMock()
|
||||
containerregistry_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
containerregistry_client.registries = {}
|
||||
|
||||
with (
|
||||
@@ -141,7 +152,7 @@ class Test_containerregistry_uses_private_link:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_ID} uses a private link."
|
||||
== f"Container Registry mock_registry from subscription {AZURE_SUBSCRIPTION_DISPLAY} uses a private link."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "mock_registry"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.cosmosdb.cosmosdb_service import Account
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_cosmosdb_account_firewall_use_selected_networks:
|
||||
def test_no_accounts(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cosmosdb_client.accounts = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_cosmosdb_account_firewall_use_selected_networks:
|
||||
|
||||
def test_accounts_no_virtual_network_filter_enabled(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
account_name = "Account Name"
|
||||
account_id = str(uuid4())
|
||||
cosmosdb_client.accounts = {
|
||||
@@ -71,7 +75,7 @@ class Test_cosmosdb_account_firewall_use_selected_networks:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_ID} has firewall rules that allow access from all networks."
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has firewall rules that allow access from all networks."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == account_name
|
||||
@@ -80,6 +84,7 @@ class Test_cosmosdb_account_firewall_use_selected_networks:
|
||||
|
||||
def test_accounts_virtual_network_filter_enabled(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
account_name = "Account Name"
|
||||
account_id = str(uuid4())
|
||||
cosmosdb_client.accounts = {
|
||||
@@ -118,7 +123,7 @@ class Test_cosmosdb_account_firewall_use_selected_networks:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_ID} has firewall rules that allow access only from selected networks."
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has firewall rules that allow access only from selected networks."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == account_name
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.cosmosdb.cosmosdb_service import Account
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_cosmosdb_account_use_aad_and_rbac:
|
||||
def test_no_accounts(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cosmosdb_client.accounts = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_cosmosdb_account_use_aad_and_rbac:
|
||||
|
||||
def test_accounts_disable_local_auth_false(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
account_name = "Account Name"
|
||||
account_id = str(uuid4())
|
||||
cosmosdb_client.accounts = {
|
||||
@@ -71,7 +75,7 @@ class Test_cosmosdb_account_use_aad_and_rbac:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_ID} is not using AAD and RBAC"
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not using AAD and RBAC"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == account_name
|
||||
@@ -80,6 +84,7 @@ class Test_cosmosdb_account_use_aad_and_rbac:
|
||||
|
||||
def test_accounts_disable_local_auth_true(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
account_name = "Account Name"
|
||||
account_id = str(uuid4())
|
||||
cosmosdb_client.accounts = {
|
||||
@@ -118,7 +123,7 @@ class Test_cosmosdb_account_use_aad_and_rbac:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_ID} is using AAD and RBAC"
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is using AAD and RBAC"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == account_name
|
||||
|
||||
+7
-2
@@ -5,7 +5,9 @@ from azure.mgmt.cosmosdb.models import PrivateEndpointConnection
|
||||
|
||||
from prowler.providers.azure.services.cosmosdb.cosmosdb_service import Account
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -13,6 +15,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_cosmosdb_account_use_private_endpoints:
|
||||
def test_no_accounts(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
cosmosdb_client.accounts = {}
|
||||
|
||||
with (
|
||||
@@ -35,6 +38,7 @@ class Test_cosmosdb_account_use_private_endpoints:
|
||||
|
||||
def test_accounts_no_private_endpoints_connections(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
account_name = "Account Name"
|
||||
account_id = str(uuid4())
|
||||
cosmosdb_client.accounts = {
|
||||
@@ -73,7 +77,7 @@ class Test_cosmosdb_account_use_private_endpoints:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_ID} is not using private endpoints connections"
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not using private endpoints connections"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == account_name
|
||||
@@ -82,6 +86,7 @@ class Test_cosmosdb_account_use_private_endpoints:
|
||||
|
||||
def test_accounts_private_endpoints_connections(self):
|
||||
cosmosdb_client = mock.MagicMock
|
||||
cosmosdb_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
account_name = "Account Name"
|
||||
account_id = str(uuid4())
|
||||
cosmosdb_client.accounts = {
|
||||
@@ -124,7 +129,7 @@ class Test_cosmosdb_account_use_private_endpoints:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_ID} is using private endpoints connections"
|
||||
== f"CosmosDB account {account_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is using private endpoints connections"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == account_name
|
||||
|
||||
+13
-2
@@ -6,7 +6,9 @@ from prowler.providers.azure.services.databricks.databricks_service import (
|
||||
ManagedDiskEncryption,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -14,6 +16,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_databricks_workspace_cmk_encryption_enabled:
|
||||
def test_no_databricks_workspaces(self):
|
||||
databricks_client = mock.MagicMock
|
||||
databricks_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
databricks_client.workspaces = {}
|
||||
|
||||
with (
|
||||
@@ -39,6 +44,9 @@ class Test_databricks_workspace_cmk_encryption_enabled:
|
||||
workspace_name = "test-workspace"
|
||||
|
||||
databricks_client = mock.MagicMock
|
||||
databricks_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
databricks_client.workspaces = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
workspace_id: DatabricksWorkspace(
|
||||
@@ -71,7 +79,7 @@ class Test_databricks_workspace_cmk_encryption_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_ID} does not have customer-managed key (CMK) encryption enabled."
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have customer-managed key (CMK) encryption enabled."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == workspace_name
|
||||
@@ -86,6 +94,9 @@ class Test_databricks_workspace_cmk_encryption_enabled:
|
||||
key_vault_uri = "test-vault-uri"
|
||||
|
||||
databricks_client = mock.MagicMock
|
||||
databricks_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
databricks_client.workspaces = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
workspace_id: DatabricksWorkspace(
|
||||
@@ -122,7 +133,7 @@ class Test_databricks_workspace_cmk_encryption_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_ID} has customer-managed key (CMK) encryption enabled with key {key_vault_uri}/{key_name}/{key_version}."
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_DISPLAY} has customer-managed key (CMK) encryption enabled with key {key_vault_uri}/{key_name}/{key_version}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == workspace_name
|
||||
|
||||
+13
-2
@@ -5,7 +5,9 @@ from prowler.providers.azure.services.databricks.databricks_service import (
|
||||
DatabricksWorkspace,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -13,6 +15,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_databricks_workspace_vnet_injection_enabled:
|
||||
def test_databricks_no_workspaces(self):
|
||||
databricks_client = mock.MagicMock
|
||||
databricks_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
databricks_client.workspaces = {}
|
||||
|
||||
with (
|
||||
@@ -37,6 +42,9 @@ class Test_databricks_workspace_vnet_injection_enabled:
|
||||
workspace_id = str(uuid4())
|
||||
workspace_name = "test-workspace"
|
||||
databricks_client = mock.MagicMock
|
||||
databricks_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
databricks_client.workspaces = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
workspace_id: DatabricksWorkspace(
|
||||
@@ -68,7 +76,7 @@ class Test_databricks_workspace_vnet_injection_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_ID} is not deployed in a customer-managed VNet (VNet Injection is not enabled)."
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_DISPLAY} is not deployed in a customer-managed VNet (VNet Injection is not enabled)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == workspace_name
|
||||
@@ -80,6 +88,9 @@ class Test_databricks_workspace_vnet_injection_enabled:
|
||||
workspace_name = "test-workspace"
|
||||
vnet_id = "test-vnet-id"
|
||||
databricks_client = mock.MagicMock
|
||||
databricks_client.subscriptions = {
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME
|
||||
}
|
||||
databricks_client.workspaces = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
workspace_id: DatabricksWorkspace(
|
||||
@@ -111,7 +122,7 @@ class Test_databricks_workspace_vnet_injection_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_ID} is deployed in a customer-managed VNet ({vnet_id})."
|
||||
== f"Databricks workspace {workspace_name} in subscription {AZURE_SUBSCRIPTION_DISPLAY} is deployed in a customer-managed VNet ({vnet_id})."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == workspace_name
|
||||
|
||||
+7
-2
@@ -6,7 +6,9 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
SecurityContactConfiguration,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -14,6 +16,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_additional_email_configured_with_a_security_contact:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {}
|
||||
|
||||
with (
|
||||
@@ -37,6 +40,7 @@ class Test_defender_additional_email_configured_with_a_security_contact:
|
||||
def test_defender_no_additional_emails(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -74,7 +78,7 @@ class Test_defender_additional_email_configured_with_a_security_contact:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is not another correct email configured for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"There is not another correct email configured for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -83,6 +87,7 @@ class Test_defender_additional_email_configured_with_a_security_contact:
|
||||
def test_defender_additional_email_configured(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -120,7 +125,7 @@ class Test_defender_additional_email_configured_with_a_security_contact:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"There is another correct email configured for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"There is another correct email configured for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
|
||||
+8
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Assesment
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_assessments_vm_endpoint_protection_installed:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_defender_assessments_vm_endpoint_protection_installed:
|
||||
|
||||
def test_defender_subscriptions_with_no_assessments(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_defender_assessments_vm_endpoint_protection_installed:
|
||||
|
||||
def test_defender_subscriptions_with_healthy_assessments(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
resource_id = str(uuid4())
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -86,13 +91,14 @@ class Test_defender_assessments_vm_endpoint_protection_installed:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Endpoint protection is set up in all VMs in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Endpoint protection is set up in all VMs in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].resource_name == "vm1"
|
||||
assert result[0].resource_id == resource_id
|
||||
|
||||
def test_defender_subscriptions_with_unhealthy_assessments(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
resource_id = str(uuid4())
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -124,7 +130,7 @@ class Test_defender_assessments_vm_endpoint_protection_installed:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Endpoint protection is not set up in all VMs in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Endpoint protection is not set up in all VMs in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].resource_name == "vm1"
|
||||
assert result[0].resource_id == resource_id
|
||||
+17
-7
@@ -6,7 +6,9 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
SecurityContactConfiguration,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -14,6 +16,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_attack_path_notifications_properly_configured:
|
||||
def test_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {}
|
||||
defender_client.audit_config = {}
|
||||
with (
|
||||
@@ -38,6 +41,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -74,7 +78,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are not enabled in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are not enabled in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
@@ -85,6 +89,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -123,7 +128,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are enabled with minimal risk level Medium in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are enabled with minimal risk level Medium in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
@@ -134,6 +139,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -172,7 +178,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are enabled with minimal risk level Medium in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are enabled with minimal risk level Medium in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
@@ -183,6 +189,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -219,7 +226,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are enabled with minimal risk level Low in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are enabled with minimal risk level Low in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
@@ -230,6 +237,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -266,7 +274,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are enabled with minimal risk level Medium in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are enabled with minimal risk level Medium in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
@@ -277,6 +285,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -313,7 +322,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are enabled with minimal risk level High in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are enabled with minimal risk level High in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
@@ -324,6 +333,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
resource_id = str(uuid4())
|
||||
contact_name = "default"
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -360,7 +370,7 @@ class Test_defender_attack_path_notifications_properly_configured:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"Attack path notifications are enabled with minimal risk level Critical in subscription {AZURE_SUBSCRIPTION_ID} for security contact {contact_name}."
|
||||
f"Attack path notifications are enabled with minimal risk level Critical in subscription {AZURE_SUBSCRIPTION_DISPLAY} for security contact {contact_name}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == contact_name
|
||||
|
||||
+10
-4
@@ -5,7 +5,9 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
AutoProvisioningSetting,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -13,6 +15,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
def test_defender_no_app_services(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.auto_provisioning_settings = {}
|
||||
|
||||
with (
|
||||
@@ -36,6 +39,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
def test_defender_auto_provisioning_log_analytics_off(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.auto_provisioning_settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"default": AutoProvisioningSetting(
|
||||
@@ -67,7 +71,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF."
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -76,6 +80,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
def test_defender_auto_provisioning_log_analytics_on(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.auto_provisioning_settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"default": AutoProvisioningSetting(
|
||||
@@ -107,7 +112,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_ID} is set to ON."
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -116,6 +121,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
def test_defender_auto_provisioning_log_analytics_on_and_off(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.auto_provisioning_settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"default": AutoProvisioningSetting(
|
||||
@@ -153,7 +159,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_ID} is set to ON."
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -162,7 +168,7 @@ class Test_defender_auto_provisioning_log_analytics_agent_vms_on:
|
||||
assert result[1].status == "FAIL"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF."
|
||||
== f"Defender Auto Provisioning Log Analytics Agents from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF."
|
||||
)
|
||||
assert result[1].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[1].resource_name == "default2"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Assesment
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_auto_provisioning_vulnerabilty_assessments_machines_on:
|
||||
def test_defender_no_app_services(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_auto_provisioning_vulnerabilty_assessments_machines_on:
|
||||
def test_defender_machines_no_vulnerability_assessment_solution(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Machines should have a vulnerability assessment solution": Assesment(
|
||||
@@ -64,7 +68,7 @@ class Test_defender_auto_provisioning_vulnerabilty_assessments_machines_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Vulnerability assessment is not set up in all VMs in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Vulnerability assessment is not set up in all VMs in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "vm1"
|
||||
@@ -73,6 +77,7 @@ class Test_defender_auto_provisioning_vulnerabilty_assessments_machines_on:
|
||||
def test_defender_machines_vulnerability_assessment_solution(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Machines should have a vulnerability assessment solution": Assesment(
|
||||
@@ -103,7 +108,7 @@ class Test_defender_auto_provisioning_vulnerabilty_assessments_machines_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Vulnerability assessment is set up in all VMs in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Vulnerability assessment is set up in all VMs in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "vm1"
|
||||
|
||||
+10
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Assesment
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_container_images_resolved_vulnerabilities:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {}
|
||||
|
||||
with (
|
||||
@@ -33,6 +36,7 @@ class Test_defender_container_images_resolved_vulnerabilities:
|
||||
|
||||
def test_defender_subscription_empty(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -55,6 +59,7 @@ class Test_defender_container_images_resolved_vulnerabilities:
|
||||
|
||||
def test_defender_subscription_no_assesment(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"": Assesment(
|
||||
@@ -85,6 +90,7 @@ class Test_defender_container_images_resolved_vulnerabilities:
|
||||
|
||||
def test_defender_subscription_assesment_unhealthy(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)": Assesment(
|
||||
@@ -128,11 +134,12 @@ class Test_defender_container_images_resolved_vulnerabilities:
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Azure running container images have unresolved vulnerabilities in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Azure running container images have unresolved vulnerabilities in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
|
||||
def test_defender_subscription_assesment_healthy(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)": Assesment(
|
||||
@@ -176,11 +183,12 @@ class Test_defender_container_images_resolved_vulnerabilities:
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Azure running container images do not have unresolved vulnerabilities in subscription '{AZURE_SUBSCRIPTION_ID}'."
|
||||
== f"Azure running container images do not have unresolved vulnerabilities in subscription '{AZURE_SUBSCRIPTION_DISPLAY}'."
|
||||
)
|
||||
|
||||
def test_defender_subscription_assesment_not_applicable(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)": Assesment(
|
||||
|
||||
+11
-3
@@ -4,7 +4,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -12,6 +14,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_container_images_scan_enabled:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
|
||||
def test_defender_subscription_empty(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
@@ -56,6 +60,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
|
||||
def test_defender_subscription_no_containers(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"NotContainers": Pricing(
|
||||
@@ -87,6 +92,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
|
||||
def test_defender_subscription_containers_no_extensions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Containers": Pricing(
|
||||
@@ -118,7 +124,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"Container image scan is disabled in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
f"Container image scan is disabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert (
|
||||
result[0].resource_id
|
||||
@@ -131,6 +137,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
|
||||
def test_defender_subscription_containers_container_images_scan_off(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Containers": Pricing(
|
||||
@@ -162,7 +169,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"Container image scan is disabled in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
f"Container image scan is disabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert (
|
||||
result[0].resource_id
|
||||
@@ -175,6 +182,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
|
||||
def test_defender_subscription_containers_container_images_scan_on(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Containers": Pricing(
|
||||
@@ -206,7 +214,7 @@ class Test_defender_container_images_scan_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"Container image scan is enabled in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
f"Container image scan is enabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert (
|
||||
result[0].resource_id
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_app_services_is_on:
|
||||
def test_defender_no_app_services(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_app_services_is_on:
|
||||
def test_defender_app_services_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"AppServices": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_app_services_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for App Services from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for App Services from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan App Services"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_app_services_is_on:
|
||||
def test_defender_app_services_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"AppServices": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_app_services_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for App Services from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for App Services from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan App Services"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_arm_is_on:
|
||||
def test_defender_no_arm(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_arm_is_on:
|
||||
def test_defender_arm_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Arm": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_arm_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for ARM from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for ARM from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan ARM"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_arm_is_on:
|
||||
def test_defender_arm_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Arm": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_arm_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for ARM from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for ARM from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan ARM"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_azure_sql_databases_is_on:
|
||||
def test_defender_no_sql_databases(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_azure_sql_databases_is_on:
|
||||
def test_defender_sql_databases_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServers": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_azure_sql_databases_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Azure SQL DB Servers from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Azure SQL DB Servers from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_azure_sql_databases_is_on:
|
||||
def test_defender_sql_databases_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServers": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_azure_sql_databases_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Azure SQL DB Servers from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Azure SQL DB Servers from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_containers_is_on:
|
||||
def test_defender_no_container_registries(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_containers_is_on:
|
||||
def test_defender_container_registries_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Containers": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_containers_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Containers from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Containers from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_containers_is_on:
|
||||
def test_defender_container_registries_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Containers": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_containers_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Containers from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Containers from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_cosmosdb_is_on:
|
||||
def test_defender_no_cosmosdb(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_cosmosdb_is_on:
|
||||
def test_defender_cosmosdb_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"CosmosDbs": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_cosmosdb_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Cosmos DB from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Cosmos DB from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Cosmos DB"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_cosmosdb_is_on:
|
||||
def test_defender_cosmosdb_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"CosmosDbs": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_cosmosdb_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Cosmos DB from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Cosmos DB from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Cosmos DB"
|
||||
|
||||
+11
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_no_databases(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_databases_sql_servers(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServers": Pricing(
|
||||
@@ -66,6 +70,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_databases_sql_server_virtual_machines(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServerVirtualMachines": Pricing(
|
||||
@@ -98,6 +103,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_databases_open_source_relation_databases(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"OpenSourceRelationalDatabases": Pricing(
|
||||
@@ -130,6 +136,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_databases_cosmosdbs(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"CosmosDbs": Pricing(
|
||||
@@ -162,6 +169,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_databases_all_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServers": Pricing(
|
||||
@@ -211,7 +219,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Databases from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Databases from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
@@ -220,6 +228,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
def test_defender_databases_cosmosdb_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServers": Pricing(
|
||||
@@ -269,7 +278,7 @@ class Test_defender_ensure_defender_for_databases_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Databases from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Databases from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_dns_is_on:
|
||||
def test_defender_no_dns(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_dns_is_on:
|
||||
def test_defender_dns_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Dns": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_dns_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for DNS from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for DNS from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan DNS"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_dns_is_on:
|
||||
def test_defender_dns_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Dns": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_dns_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for DNS from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for DNS from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan DNS"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_keyvault_is_on:
|
||||
def test_defender_no_keyvaults(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_keyvault_is_on:
|
||||
def test_defender_keyvaults_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"KeyVaults": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_keyvault_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for KeyVaults from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for KeyVaults from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan KeyVaults"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_keyvault_is_on:
|
||||
def test_defender_keyvaults_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"KeyVaults": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_keyvault_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for KeyVaults from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for KeyVaults from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan KeyVaults"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_os_relational_databases_is_on:
|
||||
def test_defender_no_os_relational_databases(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_os_relational_databases_is_on:
|
||||
def test_defender_os_relational_databases_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"OpenSourceRelationalDatabases": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_os_relational_databases_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Open-Source Relational Databases from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Open-Source Relational Databases from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
@@ -77,6 +81,7 @@ class Test_defender_ensure_defender_for_os_relational_databases_is_on:
|
||||
def test_defender_os_relational_databases_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"OpenSourceRelationalDatabases": Pricing(
|
||||
@@ -108,7 +113,7 @@ class Test_defender_ensure_defender_for_os_relational_databases_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Open-Source Relational Databases from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Open-Source Relational Databases from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_server_is_on:
|
||||
def test_defender_no_server(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_server_is_on:
|
||||
def test_defender_server_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"VirtualMachines": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_server_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Servers from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Servers from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_server_is_on:
|
||||
def test_defender_server_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"VirtualMachines": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_server_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Servers from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Servers from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Servers"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_sql_servers_is_on:
|
||||
def test_defender_no_server(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_sql_servers_is_on:
|
||||
def test_defender_server_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServerVirtualMachines": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_sql_servers_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for SQL Server VMs from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for SQL Server VMs from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan SQL Server VMs"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_sql_servers_is_on:
|
||||
def test_defender_server_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"SqlServerVirtualMachines": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_sql_servers_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for SQL Server VMs from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for SQL Server VMs from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan SQL Server VMs"
|
||||
|
||||
+7
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Pricing
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_defender_for_storage_is_on:
|
||||
def test_defender_no_server(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_defender_for_storage_is_on:
|
||||
def test_defender_server_pricing_tier_not_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"StorageAccounts": Pricing(
|
||||
@@ -65,7 +69,7 @@ class Test_defender_ensure_defender_for_storage_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Storage Accounts from subscription {AZURE_SUBSCRIPTION_ID} is set to OFF (pricing tier not standard)."
|
||||
== f"Defender plan Defender for Storage Accounts from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to OFF (pricing tier not standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Storage Accounts"
|
||||
@@ -74,6 +78,7 @@ class Test_defender_ensure_defender_for_storage_is_on:
|
||||
def test_defender_server_pricing_tier_standard(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.pricings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"StorageAccounts": Pricing(
|
||||
@@ -105,7 +110,7 @@ class Test_defender_ensure_defender_for_storage_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Defender plan Defender for Storage Accounts from subscription {AZURE_SUBSCRIPTION_ID} is set to ON (pricing tier standard)."
|
||||
== f"Defender plan Defender for Storage Accounts from subscription {AZURE_SUBSCRIPTION_DISPLAY} is set to ON (pricing tier standard)."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "Defender plan Storage Accounts"
|
||||
|
||||
+12
-6
@@ -5,7 +5,9 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
IoTSecuritySolution,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -13,6 +15,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.iot_security_solutions = {}
|
||||
|
||||
with (
|
||||
@@ -36,7 +39,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
def test_defender_no_iot_hub_solutions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.iot_security_solutions = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID}
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -58,7 +61,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"No IoT Security Solutions found in the subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"No IoT Security Solutions found in the subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].resource_name == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_id == f"/subscriptions/{AZURE_SUBSCRIPTION_ID}"
|
||||
@@ -66,6 +69,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
def test_defender_iot_hub_solution_disabled(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.iot_security_solutions = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: IoTSecuritySolution(
|
||||
@@ -94,7 +98,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The security solution iot_sec_solution is disabled in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
== f"The security solution iot_sec_solution is disabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}"
|
||||
)
|
||||
assert result[0].resource_name == "iot_sec_solution"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -102,6 +106,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
def test_defender_iot_hub_solution_enabled(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.iot_security_solutions = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: IoTSecuritySolution(
|
||||
@@ -130,7 +135,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The security solution iot_sec_solution is enabled in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"The security solution iot_sec_solution is enabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].resource_name == "iot_sec_solution"
|
||||
assert result[0].resource_id == resource_id
|
||||
@@ -140,6 +145,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
resource_id_enabled = str(uuid4())
|
||||
resource_id_disabled = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.iot_security_solutions = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id_enabled: IoTSecuritySolution(
|
||||
@@ -175,7 +181,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The security solution iot_sec_solution_enabled is enabled in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"The security solution iot_sec_solution_enabled is enabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].resource_name == "iot_sec_solution_enabled"
|
||||
assert result[0].resource_id == resource_id_enabled
|
||||
@@ -184,7 +190,7 @@ class Test_defender_ensure_iot_hub_defender_is_on:
|
||||
assert result[1].status == "FAIL"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== f"The security solution iot_sec_solution_disabled is disabled in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
== f"The security solution iot_sec_solution_disabled is disabled in subscription {AZURE_SUBSCRIPTION_DISPLAY}"
|
||||
)
|
||||
assert result[1].resource_name == "iot_sec_solution_disabled"
|
||||
assert result[1].resource_id == resource_id_disabled
|
||||
|
||||
+9
-4
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Setting
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_mcas_is_enabled:
|
||||
def test_defender_no_settings(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.settings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_mcas_is_enabled:
|
||||
def test_defender_mcas_disabled(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"MCAS": Setting(
|
||||
@@ -66,7 +70,7 @@ class Test_defender_ensure_mcas_is_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Microsoft Defender for Cloud Apps is disabled for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Microsoft Defender for Cloud Apps is disabled for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "MCAS"
|
||||
@@ -75,6 +79,7 @@ class Test_defender_ensure_mcas_is_enabled:
|
||||
def test_defender_mcas_enabled(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"MCAS": Setting(
|
||||
@@ -107,7 +112,7 @@ class Test_defender_ensure_mcas_is_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Microsoft Defender for Cloud Apps is enabled for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Microsoft Defender for Cloud Apps is enabled for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "MCAS"
|
||||
@@ -116,7 +121,7 @@ class Test_defender_ensure_mcas_is_enabled:
|
||||
def test_defender_mcas_no_settings(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.settings = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID}
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -138,7 +143,7 @@ class Test_defender_ensure_mcas_is_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Microsoft Defender for Cloud Apps not exists for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Microsoft Defender for Cloud Apps not exists for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == AZURE_SUBSCRIPTION_ID
|
||||
|
||||
+11
-4
@@ -6,7 +6,9 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
SecurityContactConfiguration,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -14,6 +16,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {}
|
||||
|
||||
with (
|
||||
@@ -37,6 +40,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
def test_defender_severity_alerts_critical(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -74,7 +78,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Notifications are not enabled for alerts with a minimum severity of high or lower in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Notifications are not enabled for alerts with a minimum severity of high or lower in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -83,6 +87,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
def test_defender_severity_alerts_high(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -121,7 +126,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Notifications are enabled for alerts with a minimum severity of high or lower (High) in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Notifications are enabled for alerts with a minimum severity of high or lower (High) in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -130,6 +135,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
def test_defender_severity_alerts_low(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -168,7 +174,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Notifications are enabled for alerts with a minimum severity of high or lower (Low) in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Notifications are enabled for alerts with a minimum severity of high or lower (Low) in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -176,6 +182,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
|
||||
def test_defender_default_security_contact_not_found(self):
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Security/securityContacts/default": SecurityContactConfiguration(
|
||||
@@ -212,7 +219,7 @@ class Test_defender_ensure_notify_alerts_severity_is_high:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Notifications are not enabled for alerts with a minimum severity of high or lower in subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Notifications are not enabled for alerts with a minimum severity of high or lower in subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
|
||||
+8
-2
@@ -6,7 +6,9 @@ from prowler.providers.azure.services.defender.defender_service import (
|
||||
SecurityContactConfiguration,
|
||||
)
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -14,6 +16,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_notify_emails_to_owners:
|
||||
def test_defender_no_subscriptions(self):
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {}
|
||||
|
||||
with (
|
||||
@@ -37,6 +40,7 @@ class Test_defender_ensure_notify_emails_to_owners:
|
||||
def test_defender_no_notify_emails_to_owners(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -76,6 +80,7 @@ class Test_defender_ensure_notify_emails_to_owners:
|
||||
def test_defender_notify_emails_to_owners_off(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -113,7 +118,7 @@ class Test_defender_ensure_notify_emails_to_owners:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The Owner role is not notified for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"The Owner role is not notified for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
@@ -122,6 +127,7 @@ class Test_defender_ensure_notify_emails_to_owners:
|
||||
def test_defender_notify_emails_to_owners(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.security_contact_configurations = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
resource_id: SecurityContactConfiguration(
|
||||
@@ -159,7 +165,7 @@ class Test_defender_ensure_notify_emails_to_owners:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"The Owner role is notified for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"The Owner role is notified for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "default"
|
||||
|
||||
+11
-4
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Assesment
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_system_updates_are_applied:
|
||||
def test_defender_no_app_services(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
def test_defender_machines_no_log_analytics_installed(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Log Analytics agent should be installed on virtual machines": Assesment(
|
||||
@@ -74,7 +78,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"System updates are not applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"System updates are not applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "vm1"
|
||||
@@ -85,6 +89,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Log Analytics agent should be installed on virtual machines": Assesment(
|
||||
@@ -125,7 +130,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"System updates are not applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"System updates are not applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "vm1"
|
||||
@@ -134,6 +139,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
def test_defender_machines_no_system_updates_installed(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Log Analytics agent should be installed on virtual machines": Assesment(
|
||||
@@ -174,7 +180,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"System updates are not applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"System updates are not applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "vm1"
|
||||
@@ -185,6 +191,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.assessments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"Log Analytics agent should be installed on virtual machines": Assesment(
|
||||
@@ -225,7 +232,7 @@ class Test_defender_ensure_system_updates_are_applied:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"System updates are applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"System updates are applied for all the VMs in the subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "vm1"
|
||||
|
||||
+9
-4
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.defender.defender_service import Setting
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_defender_ensure_wdatp_is_enabled:
|
||||
def test_defender_no_settings(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.settings = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_defender_ensure_wdatp_is_enabled:
|
||||
def test_defender_wdatp_disabled(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"WDATP": Setting(
|
||||
@@ -66,7 +70,7 @@ class Test_defender_ensure_wdatp_is_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Microsoft Defender for Endpoint integration is disabled for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Microsoft Defender for Endpoint integration is disabled for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "WDATP"
|
||||
@@ -75,6 +79,7 @@ class Test_defender_ensure_wdatp_is_enabled:
|
||||
def test_defender_wdatp_enabled(self):
|
||||
resource_id = str(uuid4())
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.settings = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"WDATP": Setting(
|
||||
@@ -107,7 +112,7 @@ class Test_defender_ensure_wdatp_is_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Microsoft Defender for Endpoint integration is enabled for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Microsoft Defender for Endpoint integration is enabled for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "WDATP"
|
||||
@@ -116,7 +121,7 @@ class Test_defender_ensure_wdatp_is_enabled:
|
||||
def test_defender_wdatp_no_settings(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.settings = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_ID}
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -138,7 +143,7 @@ class Test_defender_ensure_wdatp_is_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Microsoft Defender for Endpoint integration not exists for subscription {AZURE_SUBSCRIPTION_ID}."
|
||||
== f"Microsoft Defender for Endpoint integration not exists for subscription {AZURE_SUBSCRIPTION_DISPLAY}."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == AZURE_SUBSCRIPTION_ID
|
||||
|
||||
+14
-2
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.config import VIRTUAL_MACHINE_ADMINISTRATOR_LOGIN_ROLE_ID
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
DOMAIN,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
@@ -12,7 +14,9 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
def test_iam_no_roles(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
entra_client = mock.MagicMock
|
||||
entra_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -37,8 +41,10 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
|
||||
def test_entra_user_with_vm_access_has_mfa(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_assigment_id = str(uuid4())
|
||||
entra_client = mock.MagicMock
|
||||
entra_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
user_id = str(uuid4())
|
||||
|
||||
with (
|
||||
@@ -98,7 +104,7 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User test can access VMs in subscription {AZURE_SUBSCRIPTION_ID} but it has MFA."
|
||||
== f"User test can access VMs in subscription {AZURE_SUBSCRIPTION_DISPLAY} but it has MFA."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "test"
|
||||
@@ -106,8 +112,10 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
|
||||
def test_entra_user_with_vm_access_has_mfa_no_mfa(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_assigment_id = str(uuid4())
|
||||
entra_client = mock.MagicMock
|
||||
entra_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
user_id = str(uuid4())
|
||||
|
||||
with (
|
||||
@@ -167,7 +175,7 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"User test without MFA can access VMs in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
== f"User test without MFA can access VMs in subscription {AZURE_SUBSCRIPTION_DISPLAY}"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == "test"
|
||||
@@ -175,8 +183,10 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
|
||||
def test_entra_user_with_vm_access_has_mfa_no_user(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_assigment_id = str(uuid4())
|
||||
entra_client = mock.MagicMock
|
||||
entra_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
user_id = str(uuid4())
|
||||
|
||||
with (
|
||||
@@ -227,8 +237,10 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
|
||||
def test_entra_user_with_vm_access_has_mfa_no_role(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_assigment_id = str(uuid4())
|
||||
entra_client = mock.MagicMock
|
||||
entra_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
user_id = str(uuid4())
|
||||
|
||||
with (
|
||||
|
||||
+10
-3
@@ -4,7 +4,9 @@ from azure.mgmt.authorization.v2022_04_01.models import Permission
|
||||
|
||||
from prowler.providers.azure.services.iam.iam_service import Role
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -12,6 +14,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
def test_iam_no_roles(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.custom_roles = {}
|
||||
|
||||
with (
|
||||
@@ -36,6 +39,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
self,
|
||||
):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -76,7 +80,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_ID} has permission to administer resource locks."
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has permission to administer resource locks."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
@@ -91,6 +95,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
self,
|
||||
):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -124,7 +129,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_ID} has no permission to administer resource locks."
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has no permission to administer resource locks."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
@@ -139,6 +144,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
self,
|
||||
):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_name = "test-role"
|
||||
role_name2 = "test-role2"
|
||||
defender_client.custom_roles = {
|
||||
@@ -194,7 +200,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_ID} has permission to administer resource locks."
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has permission to administer resource locks."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
@@ -206,6 +212,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
|
||||
def test_iam_custom_roles_empty_list_but_with_key(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.custom_roles = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
|
||||
+13
-10
@@ -3,7 +3,9 @@ from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.iam.iam_service import Role, RoleAssignment
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_iam_role_user_access_admin_restricted:
|
||||
def test_iam_no_role_assignments(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
iam_client.role_assignments = {}
|
||||
iam_client.roles = {}
|
||||
|
||||
@@ -40,11 +43,11 @@ class Test_iam_role_user_access_admin_restricted:
|
||||
role_name = "User Access Administrator"
|
||||
|
||||
iam_client.subscriptions = {
|
||||
"subscription-name-1": AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME,
|
||||
}
|
||||
|
||||
iam_client.role_assignments = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
role_assignment_id: RoleAssignment(
|
||||
id=role_assignment_id,
|
||||
name="test-assignment",
|
||||
@@ -56,7 +59,7 @@ class Test_iam_role_user_access_admin_restricted:
|
||||
}
|
||||
}
|
||||
iam_client.roles = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{role_id}": Role(
|
||||
id=role_id,
|
||||
name=role_name,
|
||||
@@ -87,9 +90,9 @@ class Test_iam_role_user_access_admin_restricted:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role assignment test-assignment in subscription subscription-name-1 grants User Access Administrator role to User {agent_id}."
|
||||
== f"Role assignment test-assignment in subscription {AZURE_SUBSCRIPTION_DISPLAY} grants User Access Administrator role to User {agent_id}."
|
||||
)
|
||||
assert result[0].subscription == "subscription-name-1"
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_id == role_assignment_id
|
||||
|
||||
def test_iam_non_user_access_administrator_role_assigned(self):
|
||||
@@ -100,11 +103,11 @@ class Test_iam_role_user_access_admin_restricted:
|
||||
role_name = "Reader"
|
||||
|
||||
iam_client.subscriptions = {
|
||||
"subscription-name-1": AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME,
|
||||
}
|
||||
|
||||
iam_client.role_assignments = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
role_assignment_id: RoleAssignment(
|
||||
id=role_assignment_id,
|
||||
name="test-assignment",
|
||||
@@ -116,7 +119,7 @@ class Test_iam_role_user_access_admin_restricted:
|
||||
}
|
||||
}
|
||||
iam_client.roles = {
|
||||
"subscription-name-1": {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{role_id}": Role(
|
||||
id=role_id,
|
||||
name=role_name,
|
||||
@@ -147,7 +150,7 @@ class Test_iam_role_user_access_admin_restricted:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Role assignment test-assignment in subscription subscription-name-1 does not grant User Access Administrator role."
|
||||
== f"Role assignment test-assignment in subscription {AZURE_SUBSCRIPTION_DISPLAY} does not grant User Access Administrator role."
|
||||
)
|
||||
assert result[0].subscription == "subscription-name-1"
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_id == role_assignment_id
|
||||
+7
-2
@@ -4,7 +4,9 @@ from azure.mgmt.authorization.v2022_04_01.models import Permission
|
||||
|
||||
from prowler.providers.azure.services.iam.iam_service import Role
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -12,6 +14,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
def test_iam_no_roles(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
defender_client.custom_roles = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
|
||||
def test_iam_custom_owner_role_created_with_all(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -67,7 +71,7 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_ID} is a custom owner role."
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is a custom owner role."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
@@ -80,6 +84,7 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
|
||||
def test_iam_custom_owner_role_created_with_no_permissions(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
@@ -113,7 +118,7 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_ID} is not a custom owner role."
|
||||
== f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not a custom owner role."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
|
||||
+8
-2
@@ -2,7 +2,9 @@ from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -10,6 +12,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_keyvault_access_only_through_private_endpoints:
|
||||
def test_no_key_vaults(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_client.key_vaults = {}
|
||||
|
||||
with (
|
||||
@@ -32,6 +35,7 @@ class Test_keyvault_access_only_through_private_endpoints:
|
||||
|
||||
def test_key_vaults_no_private_endpoints(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
|
||||
@@ -78,6 +82,7 @@ class Test_keyvault_access_only_through_private_endpoints:
|
||||
|
||||
def test_key_vaults_with_private_endpoints_public_access_enabled(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
|
||||
@@ -127,7 +132,7 @@ class Test_keyvault_access_only_through_private_endpoints:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} has public network access enabled while using private endpoints."
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has public network access enabled while using private endpoints."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == keyvault_name
|
||||
@@ -136,6 +141,7 @@ class Test_keyvault_access_only_through_private_endpoints:
|
||||
|
||||
def test_key_vaults_with_private_endpoints_public_access_disabled(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
|
||||
@@ -185,7 +191,7 @@ class Test_keyvault_access_only_through_private_endpoints:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} has public network access disabled and is using private endpoints."
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has public network access disabled and is using private endpoints."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == keyvault_name
|
||||
|
||||
+10
-2
@@ -4,7 +4,9 @@ from uuid import uuid4
|
||||
from azure.mgmt.keyvault.v2023_07_01.models import KeyAttributes, VaultProperties
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -12,6 +14,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
def test_no_key_vaults(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_client.key_vaults = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
|
||||
def test_no_keys(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -75,6 +79,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
|
||||
def test_key_vaults_invalid_keys(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
key_name = "Key Name"
|
||||
@@ -127,7 +132,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} does not have an expiration date set."
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have an expiration date set."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == key_name
|
||||
@@ -136,6 +141,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
|
||||
def test_key_vaults_valid_keys(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
key_name = "Key Name"
|
||||
@@ -188,7 +194,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} has an expiration date set."
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has an expiration date set."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == key_name
|
||||
@@ -197,6 +203,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
|
||||
def test_disabled_key_skipped(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
|
||||
@@ -248,6 +255,7 @@ class Test_keyvault_key_expiration_set_in_non_rbac:
|
||||
|
||||
def test_multiple_keys_mixed_expiration(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
key_with_expiry = "key_with_expiry"
|
||||
|
||||
+11
-3
@@ -4,7 +4,9 @@ from azure.keyvault.keys import KeyRotationLifetimeAction, KeyRotationPolicy
|
||||
from azure.mgmt.keyvault.v2023_07_01.models import KeyAttributes, VaultProperties
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -12,6 +14,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_keyvault_key_rotation_enabled:
|
||||
def test_no_key_vaults(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_client.key_vaults = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
|
||||
def test_no_keys(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -75,6 +79,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
|
||||
def test_key_without_rotation_policy(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "keyvault_name"
|
||||
key_name = "key_name"
|
||||
|
||||
@@ -128,7 +133,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} does not have a rotation policy set."
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have a rotation policy set."
|
||||
)
|
||||
assert result[0].resource_name == key_name
|
||||
assert result[0].resource_id == "id"
|
||||
@@ -137,6 +142,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
|
||||
def test_key_with_rotation_policy(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "keyvault_name"
|
||||
key_name = "key_name"
|
||||
|
||||
@@ -198,7 +204,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} has a rotation policy set."
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has a rotation policy set."
|
||||
)
|
||||
assert result[0].resource_name == key_name
|
||||
assert result[0].resource_id == "id"
|
||||
@@ -207,6 +213,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
|
||||
def test_multiple_keys_mixed_rotation_policies(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "keyvault_name"
|
||||
key_with_rotation = "key_with_rotation"
|
||||
key_without_rotation = "key_without_rotation"
|
||||
@@ -306,6 +313,7 @@ class Test_keyvault_key_rotation_enabled:
|
||||
|
||||
def test_rotation_action_not_first_in_lifetime_actions(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "keyvault_name"
|
||||
key_name = "key_name"
|
||||
|
||||
@@ -372,5 +380,5 @@ class Test_keyvault_key_rotation_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} has a rotation policy set."
|
||||
== f"Key {key_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has a rotation policy set."
|
||||
)
|
||||
+11
-3
@@ -3,7 +3,9 @@ from unittest import mock
|
||||
from azure.mgmt.keyvault.v2023_07_01.models import VaultProperties
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -11,6 +13,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_keyvault_logging_enabled:
|
||||
def test_no_key_vaults(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_client.key_vaults = {}
|
||||
|
||||
with (
|
||||
@@ -37,6 +40,7 @@ class Test_keyvault_logging_enabled:
|
||||
|
||||
def test_no_diagnostic_settings(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -83,13 +87,14 @@ class Test_keyvault_logging_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key Vault name_keyvault in subscription {AZURE_SUBSCRIPTION_ID} does not have a diagnostic setting with audit logging."
|
||||
== f"Key Vault name_keyvault in subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have a diagnostic setting with audit logging."
|
||||
)
|
||||
assert result[0].resource_name == "name_keyvault"
|
||||
assert result[0].resource_id == "id"
|
||||
|
||||
def test_diagnostic_setting_without_audit_logging(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -158,13 +163,14 @@ class Test_keyvault_logging_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key Vault name_keyvault in subscription {AZURE_SUBSCRIPTION_ID} does not have a diagnostic setting with audit logging."
|
||||
== f"Key Vault name_keyvault in subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have a diagnostic setting with audit logging."
|
||||
)
|
||||
assert result[0].resource_name == "name_keyvault"
|
||||
assert result[0].resource_id == "id"
|
||||
|
||||
def test_diagnostic_setting_with_audit_logging(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -233,13 +239,14 @@ class Test_keyvault_logging_enabled:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key Vault name_keyvault in subscription {AZURE_SUBSCRIPTION_ID} has a diagnostic setting with audit logging."
|
||||
== f"Key Vault name_keyvault in subscription {AZURE_SUBSCRIPTION_DISPLAY} has a diagnostic setting with audit logging."
|
||||
)
|
||||
assert result[0].resource_name == "name_keyvault"
|
||||
assert result[0].resource_id == "id"
|
||||
|
||||
def test_multiple_diagnostic_settings_one_compliant(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -329,6 +336,7 @@ class Test_keyvault_logging_enabled:
|
||||
|
||||
def test_multiple_vaults_mixed(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
|
||||
+10
-2
@@ -4,7 +4,9 @@ from uuid import uuid4
|
||||
from azure.mgmt.keyvault.v2023_07_01.models import SecretAttributes, VaultProperties
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -12,6 +14,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
def test_no_key_vaults(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_client.key_vaults = {}
|
||||
|
||||
with (
|
||||
@@ -34,6 +37,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
|
||||
def test_no_secrets(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -76,6 +80,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
|
||||
def test_key_vaults_invalid_secrets(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
secret_name = "Secret"
|
||||
@@ -128,7 +133,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Secret {secret_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} does not have an expiration date set."
|
||||
== f"Secret {secret_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} does not have an expiration date set."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == secret_name
|
||||
@@ -137,6 +142,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
|
||||
def test_key_vaults_invalid_multiple_secrets(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
secret1_name = "Secret1"
|
||||
@@ -202,6 +208,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
|
||||
def test_key_vaults_valid_secrets(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
secret_name = "name"
|
||||
@@ -254,7 +261,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Secret {secret_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} has an expiration date set."
|
||||
== f"Secret {secret_name} in Key Vault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} has an expiration date set."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == secret_name
|
||||
@@ -263,6 +270,7 @@ class Test_keyvault_non_rbac_secret_expiration_set:
|
||||
|
||||
def test_disabled_secret_skipped(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
|
||||
|
||||
+7
-2
@@ -7,7 +7,9 @@ from azure.mgmt.keyvault.v2023_07_01.models import (
|
||||
)
|
||||
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_DISPLAY,
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
AZURE_SUBSCRIPTION_NAME,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
@@ -15,6 +17,7 @@ from tests.providers.azure.azure_fixtures import (
|
||||
class Test_keyvault_private_endpoints:
|
||||
def test_no_key_vaults(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_client.key_vaults = {}
|
||||
|
||||
with (
|
||||
@@ -37,6 +40,7 @@ class Test_keyvault_private_endpoints:
|
||||
|
||||
def test_key_vaults_no_private_endpoints(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
|
||||
@@ -82,7 +86,7 @@ class Test_keyvault_private_endpoints:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} is not using private endpoints."
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is not using private endpoints."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == keyvault_name
|
||||
@@ -91,6 +95,7 @@ class Test_keyvault_private_endpoints:
|
||||
|
||||
def test_key_vaults_using_private_endpoints(self):
|
||||
keyvault_client = mock.MagicMock
|
||||
keyvault_client.subscriptions = {AZURE_SUBSCRIPTION_ID: AZURE_SUBSCRIPTION_NAME}
|
||||
keyvault_name = "Keyvault Name"
|
||||
keyvault_id = str(uuid4())
|
||||
private_endpoint = PrivateEndpointConnectionItem(
|
||||
@@ -141,7 +146,7 @@ class Test_keyvault_private_endpoints:
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_ID} is using private endpoints."
|
||||
== f"Keyvault {keyvault_name} from subscription {AZURE_SUBSCRIPTION_DISPLAY} is using private endpoints."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == keyvault_name
|
||||
|
||||
Loaded 100 of 1373 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user