From 7400ad7c77b699e6103460692ee1e2a6863e3d41 Mon Sep 17 00:00:00 2001 From: Evgeniy Belyi Date: Tue, 19 Dec 2023 18:40:18 +0200 Subject: [PATCH] Addition of azure tests CI workflow rename --- .github/workflows/azure-ci.yml | 72 +++++ deploy/azure/cloudbeat-azure.yml | 7 + tests/configuration.py | 1 + tests/product/tests/data/azure/__init__.py | 0 .../azure/azure_app_service_test_cases.py | 126 +++++++++ .../azure_database_service_test_cases.py | 107 ++++++++ ...e_identity_access_management_test_cases.py | 32 +++ .../data/azure/azure_key_vault_test_cases.py | 31 +++ ...azure_logging_and_monitoring_test_cases.py | 259 ++++++++++++++++++ .../data/azure/azure_networking_test_cases.py | 50 ++++ .../azure_storage_account_test_cases copy.py | 146 ++++++++++ .../azure/azure_virtual_machine_test_cases.py | 88 ++++++ tests/product/tests/data/azure_test_case.py | 21 ++ .../tests/test_azure_app_service_rules.py | 54 ++++ .../test_azure_database_service_rules.py | 54 ++++ ..._azure_identity_access_management_rules.py | 54 ++++ .../tests/test_azure_key_vault_rules.py | 54 ++++ ...test_azure_logging_and_monitoring_rules.py | 54 ++++ .../tests/test_azure_networking_rules.py | 54 ++++ .../tests/test_azure_storage_account_rules.py | 54 ++++ .../tests/test_azure_virtual_machine_rules.py | 54 ++++ 21 files changed, 1372 insertions(+) create mode 100644 .github/workflows/azure-ci.yml create mode 100644 tests/product/tests/data/azure/__init__.py create mode 100644 tests/product/tests/data/azure/azure_app_service_test_cases.py create mode 100644 tests/product/tests/data/azure/azure_database_service_test_cases.py create mode 100644 tests/product/tests/data/azure/azure_identity_access_management_test_cases.py create mode 100644 tests/product/tests/data/azure/azure_key_vault_test_cases.py create mode 100644 tests/product/tests/data/azure/azure_logging_and_monitoring_test_cases.py create mode 100644 tests/product/tests/data/azure/azure_networking_test_cases.py create mode 100644 tests/product/tests/data/azure/azure_storage_account_test_cases copy.py create mode 100644 tests/product/tests/data/azure/azure_virtual_machine_test_cases.py create mode 100644 tests/product/tests/data/azure_test_case.py create mode 100644 tests/product/tests/test_azure_app_service_rules.py create mode 100644 tests/product/tests/test_azure_database_service_rules.py create mode 100644 tests/product/tests/test_azure_identity_access_management_rules.py create mode 100644 tests/product/tests/test_azure_key_vault_rules.py create mode 100644 tests/product/tests/test_azure_logging_and_monitoring_rules.py create mode 100644 tests/product/tests/test_azure_networking_rules.py create mode 100644 tests/product/tests/test_azure_storage_account_rules.py create mode 100644 tests/product/tests/test_azure_virtual_machine_rules.py diff --git a/.github/workflows/azure-ci.yml b/.github/workflows/azure-ci.yml new file mode 100644 index 0000000000..7a3df8a795 --- /dev/null +++ b/.github/workflows/azure-ci.yml @@ -0,0 +1,72 @@ +name: CIS-AZURE-CI + +on: + pull_request_target: + branches: + - main + - "[0-9]+.[0-9]+" + types: [opened, synchronize, reopened] + +jobs: + Run-CSPM-AZURE-Tests: + name: CIS AZURE integration test + if: false + runs-on: ubuntu-22.04 + timeout-minutes: 60 + permissions: + contents: 'read' + id-token: 'write' + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Init Hermit + run: ./bin/hermit env -r >> $GITHUB_ENV + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.9' + + - name: Install Poetry + run: | + curl -sSL https://install.python-poetry.org | python3 - + poetry --version + + - name: Build cloudbeat binary + uses: magefile/mage-action@v3 + with: + version: latest + args: build + + - name: Run Elasticsearch + uses: elastic/elastic-github-actions/elasticsearch@master + with: + stack-version: ${{ env.ELK_VERSION }} + security-enabled: false + + - name: Run cloudbeat in background + env: + ES_HOST: http://localhost:9200 + ES_USERNAME: elastic + ES_PASSWORD: changeme + AZURE_ACCOUNT_TYPE: single-account + AZURE_CREDENTIALS_TYPE: client-secret + AZURE_CLIENT_ID: ${{ secrets.AZURE_CREDENTIALS.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_CREDENTIALS.AZURE_TENANT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CREDENTIALS.AZURE_CLIENT_SECRET }} + run: | + ./cloudbeat -c deploy/azure/cloudbeat-azure.yml -d '*' & + + - name: Check for findings + working-directory: ./tests + env: + USE_K8S: false + run: | + poetry install + poetry run pytest -k "cspm_azure" --alluredir=./allure/results/ --clean-alluredir --maxfail=4 + + - name: Print cloudbeat logs + if: always() + run: | + cat logs/cloudbeat* diff --git a/deploy/azure/cloudbeat-azure.yml b/deploy/azure/cloudbeat-azure.yml index 420d206c0b..ee327ede32 100644 --- a/deploy/azure/cloudbeat-azure.yml +++ b/deploy/azure/cloudbeat-azure.yml @@ -2,6 +2,13 @@ cloudbeat: config: v1: benchmark: cis_azure + azure: + account_type: ${AZURE_ACCOUNT_TYPE:""} + credentials: + type: ${AZURE_CREDENTIALS_TYPE:""} + client_id: ${AZURE_CLIENT_ID:""} + tenant_id: ${AZURE_TENANT_ID:""} + client_secret: ${AZURE_CLIENT_SECRET:""} type: cloudbeat/cis_azure # Defines how often an event is sent to the output period: 30s diff --git a/tests/configuration.py b/tests/configuration.py index 04a0426177..3491fa2a4b 100644 --- a/tests/configuration.py +++ b/tests/configuration.py @@ -17,6 +17,7 @@ agent.findings_timeout = 500 agent.eks_findings_timeout = 120 agent.aws_findings_timeout = 10 +agent.azure_findings_timeout = 10 agent.cluster_type = os.getenv("CLUSTER_TYPE", "eks") # options: vanilla / eks / vanilla_aws agent.agentless = os.getenv("TEST_AGENTLESS", "false") == "true" diff --git a/tests/product/tests/data/azure/__init__.py b/tests/product/tests/data/azure/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/product/tests/data/azure/azure_app_service_test_cases.py b/tests/product/tests/data/azure/azure_app_service_test_cases.py new file mode 100644 index 0000000000..24b17d6fa0 --- /dev/null +++ b/tests/product/tests/data/azure/azure_app_service_test_cases.py @@ -0,0 +1,126 @@ +""" +This module provides Azure app service rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +App service identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + +CIS_9_4 = "CIS 9.4" +CIS_9_10 = "CIS 9.10" +CIS_9_2 = "CIS 9.2" +CIS_9_3 = "CIS 9.3" +CIS_9_5 = "CIS 9.5" +CIS_9_9 = "CIS 9.9" + +cis_azure_9_4_pass = AzureServiceCase( + rule_tag=CIS_9_4, + case_identifier="test-app-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_9_4_fail = AzureServiceCase( + rule_tag=CIS_9_4, + case_identifier="test-app-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_9_4 = { + "9.4 Ensure the web app has 'Client Certificates (Incoming client certificates)' set to 'On' expect: passed": cis_azure_9_4_pass, + "9.4 Ensure the web app has 'Client Certificates (Incoming client certificates)' set to 'On' expect: failed": cis_azure_9_4_fail, +} + +cis_azure_9_10_pass = AzureServiceCase( + rule_tag=CIS_9_10, + case_identifier="test-app-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_9_10_fail = AzureServiceCase( + rule_tag=CIS_9_10, + case_identifier="test-app-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_9_10 = { + "9.10 Ensure FTP deployments are Disabled expect: passed": cis_azure_9_10_pass, + "9.10 Ensure FTP deployments are Disabled expect: failed": cis_azure_9_10_fail, +} + +cis_azure_9_2_pass = AzureServiceCase( + rule_tag=CIS_9_2, + case_identifier="test-app-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_9_2_fail = AzureServiceCase( + rule_tag=CIS_9_2, + case_identifier="test-app-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_9_2 = { + "9.2 Ensure Web App Redirects All HTTP traffic to HTTPS in Azure App Service expect: passed": cis_azure_9_2_pass, + "9.2 Ensure Web App Redirects All HTTP traffic to HTTPS in Azure App Service expect: failed": cis_azure_9_2_fail, +} + +cis_azure_9_3_pass = AzureServiceCase( + rule_tag=CIS_9_3, + case_identifier="test-app-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_9_3_fail = AzureServiceCase( + rule_tag=CIS_9_3, + case_identifier="test-app-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_9_3 = { + "9.3 Ensure Web App is using the latest version of TLS encryption expect: passed": cis_azure_9_3_pass, + "9.3 Ensure Web App is using the latest version of TLS encryption expect: failed": cis_azure_9_3_fail, +} + +cis_azure_9_5_pass = AzureServiceCase( + rule_tag=CIS_9_5, + case_identifier="test-app-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_9_5_fail = AzureServiceCase( + rule_tag=CIS_9_5, + case_identifier="test-app-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_9_5 = { + "9.5 Ensure that Register with Azure Active Directory is enabled on App Service expect: passed": cis_azure_9_5_pass, + "9.5 Ensure that Register with Azure Active Directory is enabled on App Service expect: failed": cis_azure_9_5_fail, +} + +cis_azure_9_9_pass = AzureServiceCase( + rule_tag=CIS_9_9, + case_identifier="test-app-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_9_9_fail = AzureServiceCase( + rule_tag=CIS_9_9, + case_identifier="test-app-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_9_9 = { + "9.9 Ensure that 'HTTP Version' is the Latest, if Used to Run the Web App expect: passed": cis_azure_9_9_pass, + "9.9 Ensure that 'HTTP Version' is the Latest, if Used to Run the Web App expect: failed": cis_azure_9_9_fail, +} + +cis_azure_app_service_cases = { + **cis_azure_9_4, + **cis_azure_9_10, + **cis_azure_9_2, + **cis_azure_9_3, + **cis_azure_9_5, + **cis_azure_9_9, +} diff --git a/tests/product/tests/data/azure/azure_database_service_test_cases.py b/tests/product/tests/data/azure/azure_database_service_test_cases.py new file mode 100644 index 0000000000..aac72609ef --- /dev/null +++ b/tests/product/tests/data/azure/azure_database_service_test_cases.py @@ -0,0 +1,107 @@ +""" +This module provides Azure database service rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Database service identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + +CIS_4_5_1 = "CIS 4.5.1" +CIS_4_1_2 = "CIS 4.1.2" +CIS_4_1_4 = "CIS 4.1.4" +CIS_4_3_1 = "CIS 4.3.1" +CIS_4_4_1 = "CIS 4.4.1" + +cis_azure_4_5_1_pass = AzureServiceCase( + rule_tag=CIS_4_5_1, + case_identifier="test-database-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_4_5_1_fail = AzureServiceCase( + rule_tag=CIS_4_5_1, + case_identifier="test-database-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_4_5_1 = { + "4.5.1 Ensure That 'Firewalls & Networks' Is Limited to Use Selected Networks Instead of All Networks expect: passed": cis_azure_4_5_1_pass, + "4.5.1 Ensure That 'Firewalls & Networks' Is Limited to Use Selected Networks Instead of All Networks expect: failed": cis_azure_4_5_1_fail, +} + +cis_azure_4_1_2_pass = AzureServiceCase( + rule_tag=CIS_4_1_2, + case_identifier="test-database-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_4_1_2_fail = AzureServiceCase( + rule_tag=CIS_4_1_2, + case_identifier="test-database-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_4_1_2 = { + "4.1.2 Ensure no Azure SQL Databases allow ingress from 0.0.0.0/0 (ANY IP) expect: passed": cis_azure_4_1_2_pass, + "4.1.2 Ensure no Azure SQL Databases allow ingress from 0.0.0.0/0 (ANY IP) expect: failed": cis_azure_4_1_2_fail, +} + +cis_azure_4_1_4_pass = AzureServiceCase( + rule_tag=CIS_4_1_4, + case_identifier="test-database-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_4_1_4_fail = AzureServiceCase( + rule_tag=CIS_4_1_4, + case_identifier="test-database-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_4_1_4 = { + "4.1.4 Ensure that Azure Active Directory Admin is Configured for SQL Servers expect: passed": cis_azure_4_1_4_pass, + "4.1.4 Ensure that Azure Active Directory Admin is Configured for SQL Servers expect: failed": cis_azure_4_1_4_fail, +} + +cis_azure_4_3_1_pass = AzureServiceCase( + rule_tag=CIS_4_3_1, + case_identifier="test-database-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_4_3_1_fail = AzureServiceCase( + rule_tag=CIS_4_3_1, + case_identifier="test-database-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_4_3_1 = { + "4.3.1 Ensure 'Enforce SSL connection' is set to 'ENABLED' for PostgreSQL Database Server expect: passed": cis_azure_4_3_1_pass, + "4.3.1 Ensure 'Enforce SSL connection' is set to 'ENABLED' for PostgreSQL Database Server expect: failed": cis_azure_4_3_1_fail, +} + +cis_azure_4_4_1_pass = AzureServiceCase( + rule_tag=CIS_4_4_1, + case_identifier="test-database-service-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_4_4_1_fail = AzureServiceCase( + rule_tag=CIS_4_4_1, + case_identifier="test-database-service-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_4_4_1 = { + "4.4.1 Ensure 'Enforce SSL connection' is set to 'Enabled' for Standard MySQL Database Server expect: passed": cis_azure_4_4_1_pass, + "4.4.1 Ensure 'Enforce SSL connection' is set to 'Enabled' for Standard MySQL Database Server expect: failed": cis_azure_4_4_1_fail, +} + +cis_azure_database_service_cases = { + **cis_azure_4_5_1, + **cis_azure_4_1_2, + **cis_azure_4_1_4, + **cis_azure_4_3_1, + **cis_azure_4_4_1, +} diff --git a/tests/product/tests/data/azure/azure_identity_access_management_test_cases.py b/tests/product/tests/data/azure/azure_identity_access_management_test_cases.py new file mode 100644 index 0000000000..0e23ee5193 --- /dev/null +++ b/tests/product/tests/data/azure/azure_identity_access_management_test_cases.py @@ -0,0 +1,32 @@ +""" +This module provides Azure identity access management rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Identity access management identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + + +CIS_1_23 = "CIS 1.23" + +cis_azure_1_23_pass = AzureServiceCase( + rule_tag=CIS_1_23, + case_identifier="test-identity-access-management-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_1_23_fail = AzureServiceCase( + rule_tag=CIS_1_23, + case_identifier="test-identity-access-management-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_1_23 = { + "1.23 Ensure That No Custom Subscription Administrator Roles Exist expect: passed": cis_azure_1_23_pass, + "1.23 Ensure That No Custom Subscription Administrator Roles Exist expect: failed": cis_azure_1_23_fail, +} + +cis_azure_identity_access_management_cases = { + **cis_azure_1_23, +} diff --git a/tests/product/tests/data/azure/azure_key_vault_test_cases.py b/tests/product/tests/data/azure/azure_key_vault_test_cases.py new file mode 100644 index 0000000000..971a2aa554 --- /dev/null +++ b/tests/product/tests/data/azure/azure_key_vault_test_cases.py @@ -0,0 +1,31 @@ +""" +This module provides Azure key vault rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Key vault identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + +CIS_8_5 = "CIS 8.5" + +cis_azure_8_5_pass = AzureServiceCase( + rule_tag=CIS_8_5, + case_identifier="test-key-vault-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_8_5_fail = AzureServiceCase( + rule_tag=CIS_8_5, + case_identifier="test-key-vault-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_8_5 = { + "8.5 Ensure the Key Vault is Recoverable expect: passed": cis_azure_8_5_pass, + "8.5 Ensure the Key Vault is Recoverable expect: failed": cis_azure_8_5_fail, +} + +cis_azure_key_vault_cases = { + **cis_azure_8_5, +} diff --git a/tests/product/tests/data/azure/azure_logging_and_monitoring_test_cases.py b/tests/product/tests/data/azure/azure_logging_and_monitoring_test_cases.py new file mode 100644 index 0000000000..2972e0aa51 --- /dev/null +++ b/tests/product/tests/data/azure/azure_logging_and_monitoring_test_cases.py @@ -0,0 +1,259 @@ +""" +This module provides Azure logging and monitoring rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Logging and monitoring identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + +CIS_5_5 = "CIS 5.5" +CIS_5_2_1 = "CIS 5.2.1" +CIS_5_2_10 = "CIS 5.2.10" +CIS_5_2_2 = "CIS 5.2.2" +CIS_5_2_3 = "CIS 5.2.3" +CIS_5_2_4 = "CIS 5.2.4" +CIS_5_2_5 = "CIS 5.2.5" +CIS_5_2_6 = "CIS 5.2.6" +CIS_5_2_7 = "CIS 5.2.7" +CIS_5_2_8 = "CIS 5.2.8" +CIS_5_2_9 = "CIS 5.2.9" +CIS_5_1_2 = "CIS 5.1.2" +CIS_5_3_1 = "CIS 5.3.1" + +cis_azure_5_5_pass = AzureServiceCase( + rule_tag=CIS_5_5, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_5_fail = AzureServiceCase( + rule_tag=CIS_5_5, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_5 = { + "5.5 Ensure that SKU Basic/Consumption is not used on artifacts that need to be monitored (Particularly for Production Workloads) expect: passed": cis_azure_5_5_pass, + "5.5 Ensure that SKU Basic/Consumption is not used on artifacts that need to be monitored (Particularly for Production Workloads) expect: failed": cis_azure_5_5_fail, +} + +cis_azure_5_2_1_pass = AzureServiceCase( + rule_tag=CIS_5_2_1, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_1_fail = AzureServiceCase( + rule_tag=CIS_5_2_1, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_1 = { + "5.2.1 Ensure that Activity Log Alert exists for Create Policy Assignment expect: passed": cis_azure_5_2_1_pass, + "5.2.1 Ensure that Activity Log Alert exists for Create Policy Assignment expect: failed": cis_azure_5_2_1_fail, +} + +cis_azure_5_2_10_pass = AzureServiceCase( + rule_tag=CIS_5_2_10, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_10_fail = AzureServiceCase( + rule_tag=CIS_5_2_10, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_10 = { + "5.2.10 Ensure that Activity Log Alert exists for Delete Public IP Address rule expect: passed": cis_azure_5_2_10_pass, + "5.2.10 Ensure that Activity Log Alert exists for Delete Public IP Address rule expect: failed": cis_azure_5_2_10_fail, +} + +cis_azure_5_2_2_pass = AzureServiceCase( + rule_tag=CIS_5_2_2, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_2_fail = AzureServiceCase( + rule_tag=CIS_5_2_2, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_2 = { + "5.2.2 Ensure that Activity Log Alert exists for Delete Policy Assignment expect: passed": cis_azure_5_2_2_pass, + "5.2.2 Ensure that Activity Log Alert exists for Delete Policy Assignment expect: failed": cis_azure_5_2_2_fail, +} + +cis_azure_5_2_3_pass = AzureServiceCase( + rule_tag=CIS_5_2_3, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_3_fail = AzureServiceCase( + rule_tag=CIS_5_2_3, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_3 = { + "5.2.3 Ensure that Activity Log Alert exists for Create or Update Network Security Group expect: passed": cis_azure_5_2_3_pass, + "5.2.3 Ensure that Activity Log Alert exists for Create or Update Network Security Group expect: failed": cis_azure_5_2_3_fail, +} + +cis_azure_5_2_4_pass = AzureServiceCase( + rule_tag=CIS_5_2_4, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_4_fail = AzureServiceCase( + rule_tag=CIS_5_2_4, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_4 = { + "5.2.4 Ensure that Activity Log Alert exists for Delete Network Security Group expect: passed": cis_azure_5_2_4_pass, + "5.2.4 Ensure that Activity Log Alert exists for Delete Network Security Group expect: failed": cis_azure_5_2_4_fail, +} + +cis_azure_5_2_5_pass = AzureServiceCase( + rule_tag=CIS_5_2_5, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_5_fail = AzureServiceCase( + rule_tag=CIS_5_2_5, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_5 = { + "5.2.5 Ensure that Activity Log Alert exists for Create or Update Security Solution expect: passed": cis_azure_5_2_5_pass, + "5.2.5 Ensure that Activity Log Alert exists for Create or Update Security Solution expect: failed": cis_azure_5_2_5_fail, +} + +cis_azure_5_2_6_pass = AzureServiceCase( + rule_tag=CIS_5_2_6, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_6_fail = AzureServiceCase( + rule_tag=CIS_5_2_6, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_6 = { + "5.2.6 Ensure that Activity Log Alert exists for Delete Security Solution expect: passed": cis_azure_5_2_6_pass, + "5.2.6 Ensure that Activity Log Alert exists for Delete Security Solution expect: failed": cis_azure_5_2_6_fail, +} + +cis_azure_5_2_7_pass = AzureServiceCase( + rule_tag=CIS_5_2_7, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_7_fail = AzureServiceCase( + rule_tag=CIS_5_2_7, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_7 = { + "5.2.7 Ensure that Activity Log Alert exists for Create or Update SQL Server Firewall Rule expect: passed": cis_azure_5_2_7_pass, + "5.2.7 Ensure that Activity Log Alert exists for Create or Update SQL Server Firewall Rule expect: failed": cis_azure_5_2_7_fail, +} + +cis_azure_5_2_8_pass = AzureServiceCase( + rule_tag=CIS_5_2_8, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_8_fail = AzureServiceCase( + rule_tag=CIS_5_2_8, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_8 = { + "5.2.8 Ensure that Activity Log Alert exists for Delete SQL Server Firewall Rule expect: passed": cis_azure_5_2_8_pass, + "5.2.8 Ensure that Activity Log Alert exists for Delete SQL Server Firewall Rule expect: failed": cis_azure_5_2_8_fail, +} + +cis_azure_5_2_9_pass = AzureServiceCase( + rule_tag=CIS_5_2_9, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_2_9_fail = AzureServiceCase( + rule_tag=CIS_5_2_9, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_2_9 = { + "5.2.9 Ensure that Activity Log Alert exists for Create or Update Public IP Address rule expect: passed": cis_azure_5_2_9_pass, + "5.2.9 Ensure that Activity Log Alert exists for Create or Update Public IP Address rule expect: failed": cis_azure_5_2_9_fail, +} + +cis_azure_5_1_2_pass = AzureServiceCase( + rule_tag=CIS_5_1_2, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_1_2_fail = AzureServiceCase( + rule_tag=CIS_5_1_2, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_1_2 = { + "5.1.2 Ensure Diagnostic Setting captures appropriate categories expect: passed": cis_azure_5_1_2_pass, + "5.1.2 Ensure Diagnostic Setting captures appropriate categories expect: failed": cis_azure_5_1_2_fail, +} + +cis_azure_5_3_1_pass = AzureServiceCase( + rule_tag=CIS_5_3_1, + case_identifier="test-logging-and-monitoring-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_5_3_1_fail = AzureServiceCase( + rule_tag=CIS_5_3_1, + case_identifier="test-logging-and-monitoring-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_5_3_1 = { + "5.3.1 Ensure Application Insights are Configured expect: passed": cis_azure_5_3_1_pass, + "5.3.1 Ensure Application Insights are Configured expect: failed": cis_azure_5_3_1_fail, +} + +cis_azure_logging_and_monitoring_cases = { + **cis_azure_5_5, + **cis_azure_5_2_1, + **cis_azure_5_2_10, + **cis_azure_5_2_2, + **cis_azure_5_2_3, + **cis_azure_5_2_4, + **cis_azure_5_2_5, + **cis_azure_5_2_6, + **cis_azure_5_2_7, + **cis_azure_5_2_8, + **cis_azure_5_2_9, + **cis_azure_5_1_2, + **cis_azure_5_3_1, +} diff --git a/tests/product/tests/data/azure/azure_networking_test_cases.py b/tests/product/tests/data/azure/azure_networking_test_cases.py new file mode 100644 index 0000000000..5b8978658b --- /dev/null +++ b/tests/product/tests/data/azure/azure_networking_test_cases.py @@ -0,0 +1,50 @@ +""" +This module provides Azure networking rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Networking identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + +CIS_6_6 = "CIS 6.6" +CIS_6_5 = "CIS 6.5" + +cis_azure_6_6_pass = AzureServiceCase( + rule_tag=CIS_6_6, + case_identifier="test-networking-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_6_6_fail = AzureServiceCase( + rule_tag=CIS_6_6, + case_identifier="test-networking-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_6_6 = { + "6.6 Ensure that Network Watcher is 'Enabled' expect: passed": cis_azure_6_6_pass, + "6.6 Ensure that Network Watcher is 'Enabled' expect: failed": cis_azure_6_6_fail, +} + +cis_azure_6_5_pass = AzureServiceCase( + rule_tag=CIS_6_5, + case_identifier="test-networking-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_6_5_fail = AzureServiceCase( + rule_tag=CIS_6_5, + case_identifier="test-networking-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_6_5 = { + "6.5 Ensure that Network Security Group Flow Log retention period is 'greater than 90 days' expect: passed": cis_azure_6_5_pass, + "6.5 Ensure that Network Security Group Flow Log retention period is 'greater than 90 days' expect: failed": cis_azure_6_5_fail, +} + +cis_azure_networking_cases = { + **cis_azure_6_6, + **cis_azure_6_5, +} diff --git a/tests/product/tests/data/azure/azure_storage_account_test_cases copy.py b/tests/product/tests/data/azure/azure_storage_account_test_cases copy.py new file mode 100644 index 0000000000..36f5284cdf --- /dev/null +++ b/tests/product/tests/data/azure/azure_storage_account_test_cases copy.py @@ -0,0 +1,146 @@ +""" +This module provides Azure storage account rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Storage account identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + + +CIS_3_1 = "CIS 3.1" +CIS_3_2 = "CIS 3.2" +CIS_3_7 = "CIS 3.7" +CIS_3_8 = "CIS 3.8" +CIS_3_9 = "CIS 3.9" +CIS_3_10 = "CIS 3.10" +CIS_3_15 = "CIS 3.15" + +cis_azure_3_1_pass = AzureServiceCase( + rule_tag=CIS_3_1, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_1_fail = AzureServiceCase( + rule_tag=CIS_3_1, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_1 = { + "3.1 Ensure that 'Secure transfer required' is set to 'Enabled' expect: passed": cis_azure_3_1_pass, + "3.1 Ensure that 'Secure transfer required' is set to 'Enabled' expect: failed": cis_azure_3_1_fail, +} + +cis_azure_3_2_pass = AzureServiceCase( + rule_tag=CIS_3_2, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_2_fail = AzureServiceCase( + rule_tag=CIS_3_2, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_2 = { + "3.2 Ensure that 'Enable Infrastructure Encryption' for Each Storage Account in Azure Storage is Set to 'enabled' expect: passed": cis_azure_3_2_pass, + "3.2 Ensure that 'Enable Infrastructure Encryption' for Each Storage Account in Azure Storage is Set to 'enabled' expect: failed": cis_azure_3_2_fail, +} + +cis_azure_3_7_pass = AzureServiceCase( + rule_tag=CIS_3_7, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_7_fail = AzureServiceCase( + rule_tag=CIS_3_7, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_7 = { + "3.7 Ensure that 'Public access level' is disabled for storage accounts with blob containers expect: passed": cis_azure_3_7_pass, + "3.7 Ensure that 'Public access level' is disabled for storage accounts with blob containers expect: failed": cis_azure_3_7_fail, +} + +cis_azure_3_8_pass = AzureServiceCase( + rule_tag=CIS_3_8, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_8_fail = AzureServiceCase( + rule_tag=CIS_3_8, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_8 = { + "3.8 Ensure Default Network Access Rule for Storage Accounts is Set to Deny expect: passed": cis_azure_3_8_pass, + "3.8 Ensure Default Network Access Rule for Storage Accounts is Set to Deny expect: failed": cis_azure_3_8_fail, +} + +cis_azure_3_9_pass = AzureServiceCase( + rule_tag=CIS_3_9, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_9_fail = AzureServiceCase( + rule_tag=CIS_3_9, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_9 = { + "3.9 Ensure 'Allow Azure services on the trusted services list to access this storage account' is Enabled for Storage Account Access expect: passed": cis_azure_3_9_pass, + "3.9 Ensure 'Allow Azure services on the trusted services list to access this storage account' is Enabled for Storage Account Access expect: failed": cis_azure_3_9_fail, +} + +cis_azure_3_10_pass = AzureServiceCase( + rule_tag=CIS_3_10, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_10_fail = AzureServiceCase( + rule_tag=CIS_3_10, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_10 = { + "3.10 Ensure Private Endpoints are used to access Storage Accounts expect: passed": cis_azure_3_10_pass, + "3.10 Ensure Private Endpoints are used to access Storage Accounts expect: failed": cis_azure_3_10_fail, +} + +cis_azure_3_15_pass = AzureServiceCase( + rule_tag=CIS_3_15, + case_identifier="test-storage-account-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_3_15_fail = AzureServiceCase( + rule_tag=CIS_3_15, + case_identifier="test-storage-account-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_3_15 = { + "3.15 Ensure the 'Minimum TLS version' for storage accounts is set to 'Version 1.2' expect: passed": cis_azure_3_15_pass, + "3.15 Ensure the 'Minimum TLS version' for storage accounts is set to 'Version 1.2' expect: failed": cis_azure_3_15_fail, +} + +cis_azure_storage_account_cases = { + **cis_azure_3_1, + **cis_azure_3_2, + **cis_azure_3_7, + **cis_azure_3_8, + **cis_azure_3_9, + **cis_azure_3_10, + **cis_azure_3_15, +} diff --git a/tests/product/tests/data/azure/azure_virtual_machine_test_cases.py b/tests/product/tests/data/azure/azure_virtual_machine_test_cases.py new file mode 100644 index 0000000000..d5c1e0eb7e --- /dev/null +++ b/tests/product/tests/data/azure/azure_virtual_machine_test_cases.py @@ -0,0 +1,88 @@ +""" +This module provides Azure virtual machine rule test cases. +Cases are organized as rules. +Each rule has one or more test cases. +Virtual machine identification is performed by resource name. +""" +from ..azure_test_case import AzureServiceCase +from ..constants import RULE_PASS_STATUS, RULE_FAIL_STATUS + +CIS_7_1 = "CIS 7.1" +CIS_7_2 = "CIS 7.2" +CIS_7_3 = "CIS 7.3" +CIS_7_4 = "CIS 7.4" + +cis_azure_7_1_pass = AzureServiceCase( + rule_tag=CIS_7_1, + case_identifier="test-virtual-machine-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_7_1_fail = AzureServiceCase( + rule_tag=CIS_7_1, + case_identifier="test-virtual-machine-pass", + expected=RULE_FAIL_STATUS, +) + +cis_azure_7_1 = { + "7.1 Ensure an Azure Bastion Host Exists expect: passed": cis_azure_7_1_pass, + "7.1 Ensure an Azure Bastion Host Exists expect: failed": cis_azure_7_1_fail, +} + +cis_azure_7_2_pass = AzureServiceCase( + rule_tag=CIS_7_2, + case_identifier="test-virtual-machine-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_7_2_fail = AzureServiceCase( + rule_tag=CIS_7_2, + case_identifier="test-virtual-machine-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_7_2 = { + "7.2 Ensure Virtual Machines are utilizing Managed Disks expect: passed": cis_azure_7_2_pass, + "7.2 Ensure Virtual Machines are utilizing Managed Disks expect: failed": cis_azure_7_2_fail, +} + +cis_azure_7_3_pass = AzureServiceCase( + rule_tag=CIS_7_3, + case_identifier="test-virtual-machine-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_7_3_fail = AzureServiceCase( + rule_tag=CIS_7_3, + case_identifier="test-virtual-machine-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_7_3 = { + "7.3 Ensure that 'OS and Data' disks are encrypted with Customer Managed Key (CMK) expect: passed": cis_azure_7_3_pass, + "7.3 Ensure that 'OS and Data' disks are encrypted with Customer Managed Key (CMK) expect: failed": cis_azure_7_3_fail, +} + +cis_azure_7_4_pass = AzureServiceCase( + rule_tag=CIS_7_4, + case_identifier="test-virtual-machine-pass", + expected=RULE_PASS_STATUS, +) + +cis_azure_7_4_fail = AzureServiceCase( + rule_tag=CIS_7_4, + case_identifier="test-virtual-machine-fail", + expected=RULE_FAIL_STATUS, +) + +cis_azure_7_4 = { + "7.4 Ensure that 'Unattached disks' are encrypted with 'Customer Managed Key' (CMK) expect: passed": cis_azure_7_4_pass, + "7.4 Ensure that 'Unattached disks' are encrypted with 'Customer Managed Key' (CMK) expect: failed": cis_azure_7_4_fail, +} + +cis_azure_virtual_machine_cases = { + **cis_azure_7_1, + **cis_azure_7_2, + **cis_azure_7_3, + **cis_azure_7_4, +} diff --git a/tests/product/tests/data/azure_test_case.py b/tests/product/tests/data/azure_test_case.py new file mode 100644 index 0000000000..098bf1af25 --- /dev/null +++ b/tests/product/tests/data/azure_test_case.py @@ -0,0 +1,21 @@ +""" +This module provides Azure test case definition +""" + +from dataclasses import dataclass, astuple + +@dataclass +class AzureServiceCase: + """ + Represents Azure service test case + """ + + rule_tag: str + case_identifier: str + expected: str + + def __iter__(self): + return iter(astuple(self)) + + def __len__(self): + return len(astuple(self)) diff --git a/tests/product/tests/test_azure_app_service_rules.py b/tests/product/tests/test_azure_app_service_rules.py new file mode 100644 index 0000000000..82c69e86fe --- /dev/null +++ b/tests/product/tests/test_azure_app_service_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure App Service rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_app_service_test_cases as azure_app_service_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_app_service_rules +def test_azure_app_service_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + app_service_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=app_service_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_app_service_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_app_service_tc.cis_azure_app_service_cases.values()], + ids=[*azure_app_service_tc.cis_azure_app_service_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_database_service_rules.py b/tests/product/tests/test_azure_database_service_rules.py new file mode 100644 index 0000000000..4f8c3d75ae --- /dev/null +++ b/tests/product/tests/test_azure_database_service_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Database Service rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_database_service_test_cases as azure_database_service_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_database_service_rules +def test_azure_database_service_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + database_service_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=database_service_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_database_service_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_database_service_tc.cis_azure_database_service_cases.values()], + ids=[*azure_database_service_tc.cis_azure_database_service_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_identity_access_management_rules.py b/tests/product/tests/test_azure_identity_access_management_rules.py new file mode 100644 index 0000000000..cfc586c2a1 --- /dev/null +++ b/tests/product/tests/test_azure_identity_access_management_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Identity Access Management rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_identity_access_management_test_cases as azure_identity_access_management_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_identity_access_management_rules +def test_azure_identity_access_management_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + identity_access_management_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=identity_access_management_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_identity_access_management_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_identity_access_management_tc.cis_azure_identity_access_management_cases.values()], + ids=[*azure_identity_access_management_tc.cis_azure_identity_access_management_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_key_vault_rules.py b/tests/product/tests/test_azure_key_vault_rules.py new file mode 100644 index 0000000000..c63ec614a9 --- /dev/null +++ b/tests/product/tests/test_azure_key_vault_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Key Vault rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_key_vault_test_cases as azure_key_vault_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_key_vault_rules +def test_azure_key_vault_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + key_vault_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=key_vault_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_key_vault_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_key_vault_tc.cis_azure_key_vault_cases.values()], + ids=[*azure_key_vault_tc.cis_azure_key_vault_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_logging_and_monitoring_rules.py b/tests/product/tests/test_azure_logging_and_monitoring_rules.py new file mode 100644 index 0000000000..e7013ec995 --- /dev/null +++ b/tests/product/tests/test_azure_logging_and_monitoring_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Logging And Monitoring rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_logging_and_monitoring_test_cases as azure_logging_and_monitoring_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_logging_and_monitoring_rules +def test_azure_logging_and_monitoring_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + logging_and_monitoring_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=logging_and_monitoring_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_logging_and_monitoring_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_logging_and_monitoring_tc.cis_azure_logging_and_monitoring_cases.values()], + ids=[*azure_logging_and_monitoring_tc.cis_azure_logging_and_monitoring_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_networking_rules.py b/tests/product/tests/test_azure_networking_rules.py new file mode 100644 index 0000000000..d12ce98a77 --- /dev/null +++ b/tests/product/tests/test_azure_networking_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Networking rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_networking_test_cases as azure_networking_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_networking_rules +def test_azure_networking_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + networking_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=networking_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_networking_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_networking_tc.cis_azure_networking_cases.values()], + ids=[*azure_networking_tc.cis_azure_networking_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_storage_account_rules.py b/tests/product/tests/test_azure_storage_account_rules.py new file mode 100644 index 0000000000..ac553bbdcb --- /dev/null +++ b/tests/product/tests/test_azure_storage_account_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Storage Account rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_storage_account_test_cases as azure_storage_account_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_storage_account_rules +def test_azure_storage_account_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + storage_account_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=storage_account_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_storage_account_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_storage_account_tc.cis_azure_storage_account_cases.values()], + ids=[*azure_storage_account_tc.cis_azure_storage_account_cases.keys()], + ), +) diff --git a/tests/product/tests/test_azure_virtual_machine_rules.py b/tests/product/tests/test_azure_virtual_machine_rules.py new file mode 100644 index 0000000000..343feb7b6e --- /dev/null +++ b/tests/product/tests/test_azure_virtual_machine_rules.py @@ -0,0 +1,54 @@ +""" +CIS Azure Virtual Machine rules verification. +This module verifies correctness of retrieved findings by manipulating audit actions +""" +from datetime import datetime, timedelta +from functools import partial +import pytest +from commonlib.utils import get_ES_evaluation, res_identifier + +from product.tests.data.azure import azure_virtual_machine_test_cases as azure_virtual_machine_tc +from product.tests.parameters import register_params, Parameters +from .data.constants import RES_NAME + + +@pytest.mark.azure_virtual_machine_rules +def test_azure_virtual_machine_rules( + cspm_client, + cloudbeat_agent, + rule_tag, + case_identifier, + expected, +): + """ + This data driven test verifies rules and findings return by cloudbeat agent. + In order to add new cases @pytest.mark.parameterize section shall be updated. + Setup and teardown actions are defined in data method. + This test verifies that cloudbeat returns correct finding. + @param rule_tag: Name of rule to be verified. + @param case_identifier: Resource unique identifier + @param expected: Result to be found in finding evaluation field. + @return: None - Test Pass / Fail result is generated. + """ + virtual_machine_identifier = partial(res_identifier, RES_NAME, case_identifier) + + evaluation = get_ES_evaluation( + elastic_client=cspm_client, + timeout=cloudbeat_agent.azure_findings_timeout, + rule_tag=rule_tag, + exec_timestamp=datetime.utcnow() - timedelta(minutes=30), + resource_identifier=virtual_machine_identifier, + ) + + assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found" + assert evaluation == expected, f"Rule {rule_tag} verification failed," f"expected: {expected}, got: {evaluation}" + + +register_params( + test_azure_virtual_machine_rules, + Parameters( + ("rule_tag", "case_identifier", "expected"), + [*azure_virtual_machine_tc.cis_azure_virtual_machine_cases.values()], + ids=[*azure_virtual_machine_tc.cis_azure_virtual_machine_cases.keys()], + ), +)