From 8e8bbbfa050fb309b9827d9d216e655c85b50a58 Mon Sep 17 00:00:00 2001 From: Ablaze005 Date: Sat, 8 Aug 2026 23:37:36 +0100 Subject: [PATCH 1/3] chore(scanner): add placeholder for storage Account HTTPS enforcement rule (AZ-STORAGE-HTTPS-001) --- scanner/rules/az_stor_006.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 scanner/rules/az_stor_006.py diff --git a/scanner/rules/az_stor_006.py b/scanner/rules/az_stor_006.py new file mode 100644 index 0000000..e69de29 From c3cb109f9090a98a4f121cbe0b1bb204664360cd Mon Sep 17 00:00:00 2001 From: Ablaze005 Date: Sat, 8 Aug 2026 23:37:36 +0100 Subject: [PATCH 2/3] chore(scanner): add placeholder for storage Account HTTPS enforcement rule (AZ-STORAGE-HTTPS-001) Signed-off-by: Ablaze005 --- scanner/rules/az_stor_006.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 scanner/rules/az_stor_006.py diff --git a/scanner/rules/az_stor_006.py b/scanner/rules/az_stor_006.py new file mode 100644 index 0000000..e69de29 From 6e0e9cdaa82be115464d432456f4a3b589704f61 Mon Sep 17 00:00:00 2001 From: Ablaze005 Date: Mon, 10 Aug 2026 10:50:06 +0100 Subject: [PATCH 3/3] Add HTTPS enforcement rule and tests --- scanner/rules/az_stor_006.py | 41 ++++++++++++++++++++++++++++++ tests/test_az_stor_006.py | 49 ++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 tests/test_az_stor_006.py diff --git a/scanner/rules/az_stor_006.py b/scanner/rules/az_stor_006.py index e69de29..c8181a1 100644 --- a/scanner/rules/az_stor_006.py +++ b/scanner/rules/az_stor_006.py @@ -0,0 +1,41 @@ +""" +Rule ID: AZ-STORAGE-HTTPS-001 +Title: Storage Account HTTPS Enforcement +Severity: HIGH +Category: Storage +Description: Detects Azure Storage Accounts that do not enforce HTTPS-only traffic. +""" + +def get_storage_accounts(subscription_id): + """ + Placeholder. The scanner engine will inject real storage accounts. + Tests will mock this function. + """ + raise NotImplementedError("Scanner engine must provide storage accounts") + +def scan(subscription_id): + """ + Scans all Storage Accounts in the given subscription + and returns those that do NOT enforce HTTPS-only. + """ + + storage_accounts = get_storage_accounts(subscription_id) + findings = [] + + for account in storage_accounts: + props = account.get("properties", {}) + https_only = props.get("supportsHttpsTrafficOnly", True) + + if not https_only: + findings.append({ + "id": "AZ-STORAGE-HTTPS-001", + "resource_id": account.get("id"), + "resource_name": account.get("name"), + "resource_group": account.get("resourceGroup"), + "subscription_id": subscription_id, + "severity": "HIGH", + "category": "Storage", + "description": "Storage Account does not enforce HTTPS-only traffic.", + }) + + return findings diff --git a/tests/test_az_stor_006.py b/tests/test_az_stor_006.py new file mode 100644 index 0000000..ea7ad1a --- /dev/null +++ b/tests/test_az_stor_006.py @@ -0,0 +1,49 @@ +import unittest +import scanner.rules.az_stor_006 as rule + +class TestStorageHttpsRule(unittest.TestCase): + + def test_storage_https_disabled(self): + # Mock storage accounts + def mock_list_storage_accounts(subscription_id): + return [ + { + "id": "/subscriptions/test-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/teststorage", + "name": "teststorage", + "resourceGroup": "rg", + "properties": { + "supportsHttpsTrafficOnly": False + } + } + ] + + # Patch the function inside the rule + rule.get_storage_accounts = mock_list_storage_accounts + + findings = rule.scan("test-sub") + + self.assertEqual(len(findings), 1) + self.assertEqual(findings[0]["id"], "AZ-STORAGE-HTTPS-001") + self.assertEqual(findings[0]["severity"], "HIGH") + + def test_storage_https_enabled(self): + def mock_list_storage_accounts(subscription_id): + return [ + { + "id": "/subscriptions/test-sub/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/teststorage", + "name": "teststorage", + "resourceGroup": "rg", + "properties": { + "supportsHttpsTrafficOnly": True + } + } + ] + + rule.get_storage_accounts = mock_list_storage_accounts + + findings = rule.scan("test-sub") + + self.assertEqual(findings, []) + +if __name__ == "__main__": + unittest.main()