From b0c386fc60582973c3e4ba1883fc05c91b2ad526 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:47:17 +0200 Subject: [PATCH] fix(app): fix false positives in `app_http_logs_enabled` (#8507) Co-authored-by: Sergio Garcia --- prowler/CHANGELOG.md | 1 + .../app_http_logs_enabled.py | 4 + .../app_http_logs_enabled_test.py | 138 ++++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index f4e0e6d910..892f06b8f7 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Order requirements by ID in Prowler ThreatScore AWS compliance framework [(#8495)](https://github.com/prowler-cloud/prowler/pull/8495) - Add explicit resource name to GCP and Azure Defender checks [(#8352)](https://github.com/prowler-cloud/prowler/pull/8352) - Validation errors in Azure and M365 providers [(#8353)](https://github.com/prowler-cloud/prowler/pull/8353) +- Azure `app_http_logs_enabled` check false positives [(#8507)](https://github.com/prowler-cloud/prowler/pull/8507) - Azure `storage_geo_redundant_enabled` check false positives [(#8504)](https://github.com/prowler-cloud/prowler/pull/8504) --- diff --git a/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.py b/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.py index ea70bb708a..137ec3c494 100644 --- a/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.py +++ b/prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.py @@ -22,6 +22,10 @@ class app_http_logs_enabled(Check): report.status = "PASS" report.status_extended = f"App {app.name} has HTTP Logs enabled in diagnostic setting {diagnostic_setting.name} in subscription {subscription_name}" break + elif log.category_group == "allLogs" and log.enabled: + report.status = "PASS" + report.status_extended = f"App {app.name} has allLogs category group which includes HTTP Logs enabled in diagnostic setting {diagnostic_setting.name} in subscription {subscription_name}" + break findings.append(report) return findings diff --git a/tests/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled_test.py b/tests/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled_test.py index d318175a22..7f24fe6284 100644 --- a/tests/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled_test.py +++ b/tests/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled_test.py @@ -136,26 +136,32 @@ class Test_app_http_logs_enabled: logs=[ mock.MagicMock( category="AppServiceHTTPLogs", + category_group=None, enabled=True, ), mock.MagicMock( category="AppServiceConsoleLogs", + category_group=None, enabled=False, ), mock.MagicMock( category="AppServiceAppLogs", + category_group=None, enabled=True, ), mock.MagicMock( category="AppServiceAuditLogs", + category_group=None, enabled=False, ), mock.MagicMock( category="AppServiceIPSecAuditLogs", + category_group=None, enabled=False, ), mock.MagicMock( category="AppServicePlatformLogs", + category_group=None, enabled=False, ), ], @@ -181,26 +187,32 @@ class Test_app_http_logs_enabled: logs=[ mock.MagicMock( category="AppServiceHTTPLogs", + category_group=None, enabled=True, ), mock.MagicMock( category="AppServiceConsoleLogs", + category_group=None, enabled=True, ), mock.MagicMock( category="AppServiceAppLogs", + category_group=None, enabled=True, ), mock.MagicMock( category="AppServiceAuditLogs", + category_group=None, enabled=False, ), mock.MagicMock( category="AppServiceIPSecAuditLogs", + category_group=None, enabled=True, ), mock.MagicMock( category="AppServicePlatformLogs", + category_group=None, enabled=False, ), ], @@ -223,3 +235,129 @@ class Test_app_http_logs_enabled: result[0].status_extended == f"App app_id-2 has HTTP Logs enabled in diagnostic setting name_diagnostic_setting2 in subscription {AZURE_SUBSCRIPTION_ID}" ) + + def test_diagnostic_setting_with_all_logs_category_group(self): + app_client = mock.MagicMock + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.app.app_http_logs_enabled.app_http_logs_enabled.app_client", + new=app_client, + ), + ): + from prowler.providers.azure.services.app.app_http_logs_enabled.app_http_logs_enabled import ( + app_http_logs_enabled, + ) + from prowler.providers.azure.services.app.app_service import WebApp + from prowler.providers.azure.services.monitor.monitor_service import ( + DiagnosticSetting, + ) + + app_client.apps = { + AZURE_SUBSCRIPTION_ID: { + "resource_id3": WebApp( + resource_id="resource_id3", + name="app_id-3", + auth_enabled=True, + configurations=None, + client_cert_mode="Ignore", + https_only=False, + kind="WebApp", + identity=mock.MagicMock, + location="West Europe", + monitor_diagnostic_settings=[ + DiagnosticSetting( + id="id3/id3", + logs=[ + mock.MagicMock( + category=None, + category_group="allLogs", + enabled=True, + ), + ], + storage_account_name="storage_account_name3", + storage_account_id="storage_account_id3", + name="name_diagnostic_setting3", + ), + ], + ), + } + } + check = app_http_logs_enabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].subscription == AZURE_SUBSCRIPTION_ID + assert result[0].resource_name == "app_id-3" + 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}" + ) + + def test_diagnostic_setting_with_all_logs_category_group_disabled(self): + app_client = mock.MagicMock + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), + mock.patch( + "prowler.providers.azure.services.app.app_http_logs_enabled.app_http_logs_enabled.app_client", + new=app_client, + ), + ): + from prowler.providers.azure.services.app.app_http_logs_enabled.app_http_logs_enabled import ( + app_http_logs_enabled, + ) + from prowler.providers.azure.services.app.app_service import WebApp + from prowler.providers.azure.services.monitor.monitor_service import ( + DiagnosticSetting, + ) + + app_client.apps = { + AZURE_SUBSCRIPTION_ID: { + "resource_id4": WebApp( + resource_id="resource_id4", + name="app_id-4", + auth_enabled=True, + configurations=None, + client_cert_mode="Ignore", + https_only=False, + kind="WebApp", + identity=mock.MagicMock, + location="West Europe", + monitor_diagnostic_settings=[ + DiagnosticSetting( + id="id4/id4", + logs=[ + mock.MagicMock( + category=None, + category_group="allLogs", + enabled=False, # Disabled + ), + ], + storage_account_name="storage_account_name4", + storage_account_id="storage_account_id4", + name="name_diagnostic_setting4", + ), + ], + ), + } + } + check = app_http_logs_enabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert result[0].subscription == AZURE_SUBSCRIPTION_ID + assert result[0].resource_name == "app_id-4" + 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}" + )