From 04b43b20ae0ec2a706e48166e69de75d477b7533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20De=20la=20Torre=20Vico?= Date: Tue, 17 Feb 2026 13:30:27 +0100 Subject: [PATCH] chore(azure): enhance metadata for `vm` service (#9629) Co-authored-by: Daniel Barranquero --- prowler/CHANGELOG.md | 1 + .../vm_backup_enabled.metadata.json | 31 +++++++++------- .../vm_desired_sku_size.metadata.json | 28 ++++++++------- ...hed_disks_encrypted_with_cmk.metadata.json | 34 +++++++++++------- ...hed_disks_encrypted_with_cmk.metadata.json | 34 +++++++++++------- ...ensure_using_approved_images.metadata.json | 36 +++++++++++-------- ...m_ensure_using_managed_disks.metadata.json | 34 +++++++++++------- .../vm_jit_access_enabled.metadata.json | 33 +++++++++-------- ...x_enforce_ssh_authentication.metadata.json | 30 +++++++++------- ...ssociated_with_load_balancer.metadata.json | 36 +++++++++++-------- .../vm_scaleset_not_empty.metadata.json | 34 ++++++++++-------- ...aily_backup_retention_period.metadata.json | 28 +++++++++------ .../vm_trusted_launch_enabled.metadata.json | 31 +++++++++------- 13 files changed, 234 insertions(+), 156 deletions(-) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 0beecb94f9..da08069bd2 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -40,6 +40,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Update GCP Logging service metadata to new format [(#9648)](https://github.com/prowler-cloud/prowler/pull/9648) - Update Azure Key Vault service metadata to new format [(#9621)](https://github.com/prowler-cloud/prowler/pull/9621) - Update Azure Entra ID service metadata to new format [(#9619)](https://github.com/prowler-cloud/prowler/pull/9619) +- Update Azure Virtual Machines service metadata to new format [(#9629)](https://github.com/prowler-cloud/prowler/pull/9629) ### 🔐 Security diff --git a/prowler/providers/azure/services/vm/vm_backup_enabled/vm_backup_enabled.metadata.json b/prowler/providers/azure/services/vm/vm_backup_enabled/vm_backup_enabled.metadata.json index 8c37cd0997..a251539887 100644 --- a/prowler/providers/azure/services/vm/vm_backup_enabled/vm_backup_enabled.metadata.json +++ b/prowler/providers/azure/services/vm/vm_backup_enabled/vm_backup_enabled.metadata.json @@ -1,30 +1,37 @@ { "Provider": "azure", "CheckID": "vm_backup_enabled", - "CheckTitle": "Ensure Backups are enabled for Azure Virtual Machines", + "CheckTitle": "Virtual Machine is protected by Azure Backup", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Ensure that Microsoft Azure Backup service is in use for your Azure virtual machines (VMs) to protect against accidental deletion or corruption.", - "Risk": "Without Azure Backup enabled, VMs are at risk of data loss due to accidental deletion, corruption, or other failures, and recovery options are limited.", - "RelatedUrl": "https://docs.microsoft.com/en-us/azure/backup/backup-overview", + "Description": "**Azure VMs** are evaluated for protection by **Azure Backup** by confirming they exist as VM backup items in a **Recovery Services vault**.\n\nVMs absent from any vault item indicate no configured backup coverage.", + "Risk": "Unprotected VMs jeopardize **availability** and **integrity**. Deletion, corruption, or ransomware can wipe data, and without recovery points recovery is slow or impossible, causing extended outages, missed `RPO/RTO`, and cascading impact on dependent services.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/backup/backup-azure-arm-vms-prepare", + "https://learn.microsoft.com/en-us/azure/backup/quick-backup-vm-portal", + "https://learn.microsoft.com/en-us/azure/backup/backup-overview" + ], "Remediation": { "Code": { - "CLI": "az backup protection enable-for-vm --resource-group --vm --vault-name --policy-name DefaultPolicy", - "NativeIaC": "", - "Other": "https://learn.microsoft.com/en-us/azure/backup/quick-backup-vm-portal", - "Terraform": "" + "CLI": "az backup protection enable-for-vm --resource-group --vault-name --vm --vm-resource-group --policy-name DefaultPolicy", + "NativeIaC": "```bicep\n// Enable Azure Backup protection for an existing VM in an existing Recovery Services vault\nparam vmId string // e.g., /subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/\nparam vaultName string\nparam vaultRg string\nparam policyId string // e.g., /subscriptions//resourceGroups//providers/Microsoft.RecoveryServices/vaults//backupPolicies/\n\nresource vault 'Microsoft.RecoveryServices/vaults@2023-04-01' existing = {\n name: vaultName\n scope: resourceGroup(vaultRg)\n}\n\nvar vmRg = split(split(vmId, '/resourceGroups/')[1], '/')[0]\nvar vmName = split(vmId, '/virtualMachines/')[1]\n\nresource protect 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems@2023-02-01' = {\n // critical: this resource creates the protected item, enabling backup for the VM\n name: '${vault.name}/Azure/protectionContainers/iaasvmcontainer;iaasvmcontainerv2;${vmRg};${vmName}/protectedItems/VM;iaasvmcontainerv2;${vmRg};${vmName}'\n properties: {\n protectedItemType: 'Microsoft.Compute/virtualMachines' // critical: VM backup item type\n sourceResourceId: vmId // critical: target VM to protect\n policyId: policyId // critical: associates the VM with a backup policy\n }\n}\n```", + "Other": "1. In Azure Portal, go to Virtual machines > > Backup\n2. Select a Recovery Services vault in the same region (or create one if prompted)\n3. Choose the DefaultPolicy (or an existing VM backup policy)\n4. Click Enable backup", + "Terraform": "```hcl\n# Protect an existing VM with Azure Backup\nresource \"azurerm_backup_protected_vm\" \"\" {\n resource_group_name = \"\" # vault's resource group\n recovery_vault_name = \"\"\n source_vm_id = \"\" # critical: VM to protect\n backup_policy_id = \"\" # critical: policy that enables backup\n}\n```" }, "Recommendation": { - "Text": "Enable Azure Backup for each VM by associating it with a Recovery Services vault and a backup policy.", - "Url": "https://docs.microsoft.com/en-us/azure/backup/quick-backup-vm-portal" + "Text": "Protect all VMs with **Azure Backup** in a **Recovery Services vault** under a standardized policy. Align schedules and retention to `RPO/RTO`, use `GRS`/`ZRS` and `immutable` vault features, enforce least privilege on backup operations, automate enrollment at provisioning, and regularly test restores.", + "Url": "https://hub.prowler.com/check/vm_backup_enabled" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/vm/vm_desired_sku_size/vm_desired_sku_size.metadata.json b/prowler/providers/azure/services/vm/vm_desired_sku_size/vm_desired_sku_size.metadata.json index 98124cfb36..77b06c905e 100644 --- a/prowler/providers/azure/services/vm/vm_desired_sku_size/vm_desired_sku_size.metadata.json +++ b/prowler/providers/azure/services/vm/vm_desired_sku_size/vm_desired_sku_size.metadata.json @@ -1,27 +1,31 @@ { "Provider": "azure", "CheckID": "vm_desired_sku_size", - "CheckTitle": "Ensure that your virtual machine instances are using SKU sizes that are approved by your organization", + "CheckTitle": "Virtual Machine uses an organization-approved SKU size", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", - "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "Severity": "medium", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Ensure that your virtual machine instances are using SKU sizes that are approved by your organization. This check requires configuration of the desired VM SKU sizes in the Prowler configuration file.", - "Risk": "Setting limits for the SKU size(s) of the virtual machine instances provisioned in your Microsoft Azure account can help you to manage better your cloud compute power, address internal compliance requirements and prevent unexpected charges on your Azure monthly bill. Without proper SKU size controls, organizations may face cost overruns and compliance violations.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/overview", + "Description": "**Azure virtual machines** are compared against an organization **allowlist of VM size SKUs** defined in `desired_vm_sku_sizes`.\n\nInstances using sizes outside this list are flagged as non-standard.", + "Risk": "Unrestricted VM sizes enable over-provisioned or exotic SKUs, leading to:\n- Sudden cost spikes and quota exhaustion (availability)\n- Use of hardware lacking required security features (confidentiality/integrity)\n- Abuse by compromised accounts for cryptomining at scale", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/resize-vm", + "https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/overview" + ], "Remediation": { "Code": { - "CLI": "az policy assignment create --display-name 'Allowed VM SKU Sizes' --policy cccc23c7-8427-4f53-ad12-b6a63eb452b3 -p '{\"listOfAllowedSKUs\": {\"value\": [\"\", \"\"]}}' --scope /subscriptions/", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "az vm resize --resource-group --name --size ", + "NativeIaC": "```bicep\n// Resize VM to an approved SKU\nresource vm 'Microsoft.Compute/virtualMachines@2023-09-01' = {\n name: ''\n location: ''\n properties: {\n hardwareProfile: {\n vmSize: '' // CRITICAL: sets VM to an approved size so the check passes\n }\n }\n}\n```", + "Other": "1. In Azure Portal, go to Virtual machines and select the VM\n2. Under Availability + scale, select Size\n3. Choose an approved size (e.g., ) and click Resize\n4. If the size isn't listed, Stop (deallocate) the VM, then retry Resize", + "Terraform": "```hcl\n# Enforce allowed VM SKUs via Azure Policy\nresource \"azurerm_policy_assignment\" \"\" {\n name = \"\"\n scope = \"/subscriptions/\"\n policy_definition_id = \"/providers/Microsoft.Authorization/policyDefinitions/\"\n\n parameters = jsonencode({\n listOfAllowedSKUs = { value = [\"\", \"\"] } # CRITICAL: only these SKUs are allowed\n })\n}\n```" }, "Recommendation": { - "Text": "1. Define and document your organization's approved VM SKU sizes based on workload requirements, cost constraints, and compliance needs. 2. Implement Azure Policy to enforce VM size restrictions across your subscriptions. 3. Use the 'Allowed virtual machine size SKUs' built-in policy to restrict VM creation to approved sizes. 4. Regularly review and update your approved SKU list based on changing business requirements and cost optimization goals. 5. Monitor VM usage and costs to ensure compliance with your SKU size policies.", - "Url": "https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/resize-vm" + "Text": "Adopt a **least privilege, policy-enforced allowlist** of VM size SKUs per workload tier and region.\n- Deny creation of non-approved sizes across scopes\n- Require exception reviews with time-bound overrides\n- Reassess the list regularly for cost, performance, and compliance\n- Monitor provisioning and cost anomalies for drift", + "Url": "https://hub.prowler.com/check/vm_desired_sku_size" } }, "Categories": [], diff --git a/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json b/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json index d880672dcb..7887e4ffae 100644 --- a/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json +++ b/prowler/providers/azure/services/vm/vm_ensure_attached_disks_encrypted_with_cmk/vm_ensure_attached_disks_encrypted_with_cmk.metadata.json @@ -1,30 +1,38 @@ { "Provider": "azure", "CheckID": "vm_ensure_attached_disks_encrypted_with_cmk", - "CheckTitle": "Ensure that 'OS and Data' disks are encrypted with Customer Managed Key (CMK)", + "CheckTitle": "Virtual Machine OS or data disk is encrypted with a customer-managed key (CMK)", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", - "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "Severity": "medium", + "ResourceType": "microsoft.compute/disks", "ResourceGroup": "compute", - "Description": "Ensure that OS disks (boot volumes) and data disks (non-boot volumes) are encrypted with CMK (Customer Managed Keys). Customer Managed keys can be either ADE or Server Side Encryption (SSE).", - "Risk": "Encrypting the IaaS VM's OS disk (boot volume) and Data disks (non-boot volume) ensures that the entire content is fully unrecoverable without a key, thus protecting the volume from unwanted reads. PMK (Platform Managed Keys) are enabled by default in Azure-managed disks and allow encryption at rest. CMK is recommended because it gives the customer the option to control which specific keys are used for the encryption and decryption of the disk. The customer can then change keys and increase security by disabling them instead of relying on the PMK key that remains unchanging. There is also the option to increase security further by using automatically rotating keys so that access to disk is ensured to be limited. Organizations should evaluate what their security requirements are, however, for the data stored on the disk. For high-risk data using CMK is a must, as it provides extra steps of security. If the data is low risk, PMK is enabled by default and provides sufficient data security.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machines/disk-encryption-overview", + "Description": "**Attached Azure managed disks** (OS and data) are assessed to confirm encryption uses **customer-managed keys** (`CMK`) via disk encryption sets rather than platform-managed keys. Scope includes disks currently attached to VMs, evaluating their encryption type to verify CMK is applied.", + "Risk": "Without **CMK**, you lose control over key lifecycle and access. This weakens confidentiality and compliance: you can't enforce independent rotation, promptly revoke keys to crypto-lock stolen copies/snapshots, or separate duties. Misuse or compromise may keep data readable beyond your trust boundary.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/virtual-machines/disk-encryption-overview", + "https://support.icompaas.com/support/solutions/articles/62000229895-ensure-that-os-and-data-disks-are-encrypted-with-customer-managed-key-cmk-", + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/sse-boot-disk-cmk.html#", + "https://learn.microsoft.com/en-us/azure/security/fundamentals/data-encryption-best-practices#protect-data-at-rest" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/sse-boot-disk-cmk.html#", - "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/bc_azr_general_1#terraform" + "CLI": "az disk update -g -n --encryption-type EncryptionAtRestWithCustomerKey --disk-encryption-set ", + "NativeIaC": "```bicep\n// Encrypt a managed disk with a customer-managed key via Disk Encryption Set (DES)\nresource disk 'Microsoft.Compute/disks@2023-10-02' = {\n name: ''\n location: ''\n sku: {\n name: 'Standard_LRS'\n }\n properties: {\n creationData: {\n createOption: 'Empty'\n }\n diskSizeGB: 32\n\n // CRITICAL: Use CMK by attaching a Disk Encryption Set (DES)\n // This switches encryption from platform-managed to customer-managed\n encryption: {\n type: 'EncryptionAtRestWithCustomerKey' // critical: CMK\n diskEncryptionSetId: '' // critical: DES resource ID\n }\n }\n}\n```", + "Other": "1. In Azure Portal, open the target VM and click Stop to deallocate it.\n2. For each data disk: Go to VM > Disks > select the data disk > Detach > Save.\n3. In the portal search box, open Disks, select the detached disk > Encryption.\n4. Set Encryption type to Customer-managed key (Disk encryption set), select your Disk Encryption Set, then Save.\n5. Reattach the disk: VM > Disks > Add data disk (select the same disk) > Save.\n6. For OS disk, use Swap OS disk: create a new managed disk from a snapshot/image with Encryption type = Customer-managed key (select the same DES), then VM > Disks > Swap OS disk and choose that disk.\n7. Start the VM.", + "Terraform": "```hcl\n# Encrypt a managed disk with a customer-managed key via Disk Encryption Set (DES)\nresource \"azurerm_managed_disk\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n storage_account_type = \"Standard_LRS\"\n create_option = \"Empty\"\n disk_size_gb = 32\n\n # CRITICAL: Attach DES to enable SSE with CMK and pass the check\n disk_encryption_set_id = \"\" # critical: DES ID\n}\n```" }, "Recommendation": { - "Text": "Note: Disks must be detached from VMs to have encryption changed. 1. Go to Virtual machines 2. For each virtual machine, go to Settings 3. Click on Disks 4. Click the ellipsis (...), then click Detach to detach the disk from the VM 5. Now search for Disks and locate the unattached disk 6. Click the disk then select Encryption 7. Change your encryption type, then select your encryption set 8. Click Save 9. Go back to the VM and re-attach the disk", - "Url": "https://learn.microsoft.com/en-us/azure/security/fundamentals/data-encryption-best-practices#protect-data-at-rest" + "Text": "Use **CMK** with disk encryption sets for all attached OS and data disks.\n- Enforce **least privilege** on key usage and scope\n- Enable periodic key rotation and auditing\n- Store keys in HSM-backed vaults; separate key and data admins\n- Combine with **encryption at host** to cover temp disks and caches", + "Url": "https://hub.prowler.com/check/vm_ensure_attached_disks_encrypted_with_cmk" } }, - "Categories": [], + "Categories": [ + "encryption" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Using CMK/BYOK will entail additional management of keys." diff --git a/prowler/providers/azure/services/vm/vm_ensure_unattached_disks_encrypted_with_cmk/vm_ensure_unattached_disks_encrypted_with_cmk.metadata.json b/prowler/providers/azure/services/vm/vm_ensure_unattached_disks_encrypted_with_cmk/vm_ensure_unattached_disks_encrypted_with_cmk.metadata.json index 0bf4e96e91..8675865160 100644 --- a/prowler/providers/azure/services/vm/vm_ensure_unattached_disks_encrypted_with_cmk/vm_ensure_unattached_disks_encrypted_with_cmk.metadata.json +++ b/prowler/providers/azure/services/vm/vm_ensure_unattached_disks_encrypted_with_cmk/vm_ensure_unattached_disks_encrypted_with_cmk.metadata.json @@ -1,30 +1,38 @@ { "Provider": "azure", "CheckID": "vm_ensure_unattached_disks_encrypted_with_cmk", - "CheckTitle": "Ensure that 'Unattached disks' are encrypted with 'Customer Managed Key' (CMK)", + "CheckTitle": "Unattached disk is encrypted with a customer-managed key (CMK)", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", - "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "Severity": "medium", + "ResourceType": "microsoft.compute/disks", "ResourceGroup": "compute", - "Description": "Ensure that unattached disks in a subscription are encrypted with a Customer Managed Key (CMK).", - "Risk": "Managed disks are encrypted by default with Platform-managed keys. Using Customer-managed keys may provide an additional level of security or meet an organization's regulatory requirements. Encrypting managed disks ensures that its entire content is fully unrecoverable without a key and thus protects the volume from unwarranted reads. Even if the disk is not attached to any of the VMs, there is always a risk where a compromised user account with administrative access to VM service can mount/attach these data disks, which may lead to sensitive information disclosure and tampering.", - "RelatedUrl": "https://docs.microsoft.com/en-us/azure/security/fundamentals/azure-disk-encryption-vms-vmss", + "Description": "Unattached **Azure managed disks** use **Customer-Managed Keys** (`CMK`) for server-side encryption rather than platform-managed keys. Only disks not currently attached to a VM are in scope.", + "Risk": "Without **CMK**, you lack independent key control on unattached disks. A compromised admin could attach a disk to read or alter data before you can revoke access. Missing customer-controlled rotation and revocation weakens **confidentiality** and **integrity**, and can hinder data-sovereignty compliance.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/sse-unattached-disk-cmk.html#", + "https://learn.microsoft.com/en-us/azure/security/fundamentals/data-encryption-best-practices#protect-data-at-rest", + "https://learn.microsoft.com/en-us/rest/api/compute/disks/delete?view=rest-compute-2023-10-02&tabs=HTTP", + "https://learn.microsoft.com/en-us/azure/virtual-machines/disk-encryption-overview" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/sse-unattached-disk-cmk.html#", - "Terraform": "" + "CLI": "az disk update -g -n --encryption-type EncryptionAtRestWithCustomerKey --disk-encryption-set ", + "NativeIaC": "```bicep\n// Update an existing managed disk to use a customer-managed key via Disk Encryption Set\nresource example_disk 'Microsoft.Compute/disks@2023-08-01' = {\n name: ''\n location: ''\n properties: {\n encryption: {\n type: 'EncryptionAtRestWithCustomerKey' // CRITICAL: switch to CMK-based encryption\n diskEncryptionSetId: '' // CRITICAL: DES resource ID that holds the CMK\n }\n }\n}\n```", + "Other": "1. In Azure portal, go to Disks and open the unattached disk\n2. Select Encryption\n3. Set Encryption type to Customer-managed key\n4. Select the Disk encryption set to use\n5. Click Save", + "Terraform": "```hcl\n# Associate an unattached managed disk with a Disk Encryption Set (CMK)\nresource \"azurerm_managed_disk\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n create_option = \"Empty\"\n disk_size_gb = 1\n\n disk_encryption_set_id = \"\" # CRITICAL: enables CMK by linking the Disk Encryption Set\n}\n```" }, "Recommendation": { - "Text": "If data stored in the disk is no longer useful, refer to Azure documentation to delete unattached data disks at: https://learn.microsoft.com/en-us/rest/api/compute/disks/delete?view=rest-compute-2023-10-02&tabs=HTTP", - "Url": "https://learn.microsoft.com/en-us/azure/security/fundamentals/data-encryption-best-practices#protect-data-at-rest" + "Text": "Encrypt unattached disks with **CMK** backed by a hardened key service. Enforce **least privilege** for disk attachment and key usage, enable key rotation and auditing, and restrict access to keys. Apply lifecycle governance-*remove stale disks*-to reduce exposure and support **defense in depth**.", + "Url": "https://hub.prowler.com/check/vm_ensure_unattached_disks_encrypted_with_cmk" } }, - "Categories": [], + "Categories": [ + "encryption" + ], "DependsOn": [], "RelatedTo": [], "Notes": "You must have your key vault set up to utilize this. Encryption is available only on Standard tier VMs. This might cost you more. Utilizing and maintaining Customer-managed keys will require additional work to create, protect, and rotate keys." diff --git a/prowler/providers/azure/services/vm/vm_ensure_using_approved_images/vm_ensure_using_approved_images.metadata.json b/prowler/providers/azure/services/vm/vm_ensure_using_approved_images/vm_ensure_using_approved_images.metadata.json index 572e2560b4..92c4853fcb 100644 --- a/prowler/providers/azure/services/vm/vm_ensure_using_approved_images/vm_ensure_using_approved_images.metadata.json +++ b/prowler/providers/azure/services/vm/vm_ensure_using_approved_images/vm_ensure_using_approved_images.metadata.json @@ -1,30 +1,36 @@ { "Provider": "azure", "CheckID": "vm_ensure_using_approved_images", - "CheckTitle": "Ensure that Azure VMs are using an approved machine image.", + "CheckTitle": "Virtual Machine uses an approved custom machine image", "CheckType": [], "ServiceName": "vm", - "SubServiceName": "image", - "ResourceIdTemplate": "/subscriptions//resourceGroups//providers/Microsoft.Compute/images/", - "Severity": "medium", - "ResourceType": "Microsoft.Compute/images", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "high", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Ensure that all your Azure virtual machine instances are launched from approved machine images only.", - "Risk": "An approved machine image is a custom virtual machine (VM) image that contains a pre-configured OS and a well-defined stack of server software approved by Azure, fully configured to run your application. Using approved (golden) machine images to launch new VM instances within your Azure cloud environment brings major benefits such as fast and stable application deployment and scaling, secure application stack upgrades, and versioning.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machines/windows/create-vm-generalized-managed", + "Description": "**Azure VMs** are evaluated for use of an **approved custom image** by inspecting the VM image reference. The expected format is a subscription-scoped ID like `/subscriptions/.../providers/Microsoft.Compute/images/`, not marketplace, gallery, or community sources.", + "Risk": "Using **unapproved images** undermines **integrity** and **confidentiality** by introducing unknown packages, misconfigurations, or malware. Attackers can implant backdoors, weaken hardening, and bypass baselines, enabling data exfiltration and lateral movement, and harming **availability** with unpatched software.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/approved-machine-image.html", + "https://learn.microsoft.com/en-us/azure/virtual-machines/windows/create-vm-generalized-managed" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/approved-machine-image.html", - "Terraform": "" + "CLI": "az vm create --resource-group --name --image /subscriptions//resourceGroups//providers/Microsoft.Compute/images/ --admin-username azureuser --generate-ssh-keys", + "NativeIaC": "```bicep\n// Create a VM using an approved custom managed image\nparam location string = resourceGroup().location\nparam nicId string\nparam adminUsername string\nparam adminPassword string\n\nresource vm 'Microsoft.Compute/virtualMachines@2023-09-01' = {\n name: ''\n location: location\n properties: {\n hardwareProfile: { vmSize: 'Standard_DS1_v2' }\n storageProfile: {\n imageReference: {\n id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/images/' // CRITICAL: use managed image ID to pass check\n }\n osDisk: { createOption: 'FromImage' }\n }\n osProfile: {\n computerName: ''\n adminUsername: adminUsername\n adminPassword: adminPassword\n }\n networkProfile: {\n networkInterfaces: [{ id: nicId }]\n }\n }\n}\n```", + "Other": "1. In Azure Portal, go to Virtual machines > Create > Azure virtual machine\n2. Under Image, click See all images, then select the My Images tab\n3. Choose the approved managed image (type: Microsoft.Compute/images)\n4. Complete required basics and create the VM\n5. If replacing a non-compliant VM, migrate workload and delete the old VM", + "Terraform": "```hcl\n# VM created from an approved custom managed image\nresource \"azurerm_windows_virtual_machine\" \"\" {\n name = \"\"\n resource_group_name = \"\"\n location = \"\"\n size = \"Standard_DS1_v2\"\n admin_username = \"\"\n admin_password = \"\"\n network_interface_ids = [\"\"]\n\n source_image_id = \"/subscriptions//resourceGroups//providers/Microsoft.Compute/images/\" # CRITICAL: managed image ID ensures PASS\n\n os_disk {\n caching = \"ReadWrite\"\n storage_account_type = \"Standard_LRS\"\n }\n}\n```" }, "Recommendation": { - "Text": "Re-create the required VM instances using the approved (golden) machine image.", - "Url": "https://docs.microsoft.com/en-us/azure/virtual-machines/windows/create-vm-generalized-managed" + "Text": "Standardize on **golden images** maintained in an Azure Compute Gallery or managed images.\n- Harden and patch each release; scan for vulnerabilities\n- Restrict who can create/publish images (**least privilege**)\n- Enforce deployments only from approved images via policy\n- Version, sign, and retire images regularly", + "Url": "https://hub.prowler.com/check/vm_ensure_using_approved_images" } }, - "Categories": [], + "Categories": [ + "software-supply-chain" + ], "DependsOn": [], "RelatedTo": [], "Notes": "This check only validates if the VM was launched from a custom image. It does not validate the image content or security baseline." diff --git a/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json b/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json index acd819e71b..4d43280e71 100644 --- a/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json +++ b/prowler/providers/azure/services/vm/vm_ensure_using_managed_disks/vm_ensure_using_managed_disks.metadata.json @@ -1,30 +1,38 @@ { "Provider": "azure", "CheckID": "vm_ensure_using_managed_disks", - "CheckTitle": "Ensure Virtual Machines are utilizing Managed Disks", + "CheckTitle": "Virtual Machine uses managed disks for OS and data disks", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", - "Severity": "medium", - "ResourceType": "Microsoft.Compute/virtualMachines", + "Severity": "high", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Migrate blob-based VHDs to Managed Disks on Virtual Machines to exploit the default features of this configuration. The features include: 1. Default Disk Encryption 2. Resilience, as Microsoft will managed the disk storage and move around if underlying hardware goes faulty 3. Reduction of costs over storage accounts", - "Risk": "Managed disks are by default encrypted on the underlying hardware, so no additional encryption is required for basic protection. It is available if additional encryption is required. Managed disks are by design more resilient that storage accounts. For ARM-deployed Virtual Machines, Azure Adviser will at some point recommend moving VHDs to managed disks both from a security and cost management perspective.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machines/unmanaged-disks-deprecation", + "Description": "**Azure virtual machines** use **managed disks** for the OS disk and every data disk, rather than page blob VHDs in storage accounts.\n\nThe evaluation confirms that all attached VM disks are managed.", + "Risk": "Using **unmanaged disks** ties VM data to storage account keys and SAS, increasing exposure of disk contents if those secrets leak (**confidentiality/integrity**). Limited platform resiliency and quotas increase **availability** risk. With Azure retiring unmanaged disks on `2026-03-31`, such VMs may be stopped and unable to start.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/virtual-machines/unmanaged-disks-deprecation", + "https://learn.microsoft.com/en-us/azure/virtual-machines/windows/convert-unmanaged-to-managed-disks", + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/managed-disks-in-use.html", + "https://learn.microsoft.com/en-us/security/benchmark/azure/security-controls-v3-data-protection#dp-4-enable-data-at-rest-encryption-by-default" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/managed-disks-in-use.html", - "Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-virtual-machines-are-utilizing-managed-disks#terraform" + "CLI": "az vm convert --resource-group --name ", + "NativeIaC": "```bicep\n// VM configured to use a managed OS disk\nresource vm 'Microsoft.Compute/virtualMachines@2023-09-01' = {\n name: ''\n location: resourceGroup().location\n properties: {\n hardwareProfile: { vmSize: 'Standard_DS1_v2' }\n storageProfile: {\n osDisk: {\n name: 'osdisk'\n osType: 'Linux'\n createOption: 'Attach'\n managedDisk: {\n id: '' // CRITICAL: attaching a managed disk makes the VM use managed disks\n }\n }\n }\n networkProfile: { networkInterfaces: [ { id: '' } ] }\n }\n}\n```", + "Other": "1. In Azure Portal, go to Virtual machines > select your VM\n2. Click Stop to deallocate the VM\n3. In the VM menu, select Disks\n4. Click Migrate to managed disks, then click Migrate to start\n5. After migration completes, click Start to power on the VM\n6. If the VM is in an availability set: first go to Availability sets > select the set > Convert to managed (SKU: Aligned), then repeat steps 1-5", + "Terraform": "```hcl\n# VM attached to a managed OS disk\nresource \"azurerm_virtual_machine\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n network_interface_ids = [\"\"]\n vm_size = \"Standard_DS1_v2\"\n\n storage_os_disk {\n name = \"osdisk\"\n create_option = \"Attach\"\n managed_disk_id = \"\" # CRITICAL: use a managed disk for the OS disk\n }\n}\n```" }, "Recommendation": { - "Text": "1. Using the search feature, go to Virtual Machines 2. Select the virtual machine you would like to convert 3. Select Disks in the menu for the VM 4. At the top select Migrate to managed disks 5. You may follow the prompts to convert the disk and finish by selecting Migrate to start the process", - "Url": "https://docs.microsoft.com/en-us/security/benchmark/azure/security-controls-v3-data-protection#dp-4-enable-data-at-rest-encryption-by-default" + "Text": "Adopt **managed disks** for all VM OS and data volumes.\n- Enforce **least privilege** via RBAC at disk scope\n- Use encryption at rest; prefer `CMEK` when mandated\n- Apply backups/snapshots and zone-aware designs for **defense in depth**\n- After migration, delete orphaned VHD blobs to avoid data exposure and cost.", + "Url": "https://hub.prowler.com/check/vm_ensure_using_managed_disks" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "There are additional costs for managed disks based off of disk space allocated. When converting to managed disks, VMs will be powered off and back on." diff --git a/prowler/providers/azure/services/vm/vm_jit_access_enabled/vm_jit_access_enabled.metadata.json b/prowler/providers/azure/services/vm/vm_jit_access_enabled/vm_jit_access_enabled.metadata.json index a08397637d..490cfa7d2e 100644 --- a/prowler/providers/azure/services/vm/vm_jit_access_enabled/vm_jit_access_enabled.metadata.json +++ b/prowler/providers/azure/services/vm/vm_jit_access_enabled/vm_jit_access_enabled.metadata.json @@ -1,30 +1,35 @@ { "Provider": "azure", "CheckID": "vm_jit_access_enabled", - "CheckTitle": "Enable Just-In-Time Access for Virtual Machines", + "CheckTitle": "Virtual Machine has Just-in-Time (JIT) access enabled", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", - "ResourceIdTemplate": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}", - "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Ensure that Microsoft Azure virtual machines are configured to use Just-in-Time (JIT) access.", - "Risk": "Without JIT access, management ports such as 22 (SSH) and 3389 (RDP) may be exposed, increasing the risk of brute-force and DDoS attacks.", - "RelatedUrl": "https://docs.microsoft.com/en-us/azure/security-center/security-center-just-in-time?tabs=jit-config-asc%2Cjit-request-asc", + "Description": "**Azure virtual machines** are associated with a **Just-in-Time (JIT) network access policy** that opens management ports only for approved, time-bound requests from specified source IPs.", + "Risk": "Without **JIT**, management ports like `22`/`3389` may stay reachable, enabling:\n- brute-force and password-spray attempts\n- exploitation of remote access flaws or stolen keys\nThis threatens **confidentiality** (data exfiltration), **integrity** (unauthorized changes), and **availability** (service disruption).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/defender-for-cloud/enable-just-in-time-access?tabs=jit-config-asc%2Cjit-request-asc" + ], "Remediation": { "Code": { - "CLI": "az security jit-policy list --query '[*].virtualMachines[*].id | []'", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "az rest --method PUT --url \"https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Security/locations//jitNetworkAccessPolicies/default?api-version=2020-01-01\" --body '{\"kind\":\"Basic\",\"properties\":{\"virtualMachines\":[{\"id\":\"/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/\",\"ports\":[{\"number\":22,\"protocol\":\"*\",\"allowedSourceAddressPrefix\":[\"*\"],\"maxRequestAccessDuration\":\"PT3H\"}]}]}}'", + "NativeIaC": "```bicep\n// Bicep: Enable JIT for a VM by creating a JIT policy that references the VM\nparam location string = \"\"\nparam vmId string = \"/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/\"\n\nresource jit 'Microsoft.Security/locations/jitNetworkAccessPolicies@2020-01-01' = {\n name: '${location}/default'\n properties: {\n virtualMachines: [\n {\n id: vmId // Critical: Adding the VM ID enables JIT for this VM\n ports: [\n {\n number: 22\n protocol: '*'\n allowedSourceAddressPrefix: ['*']\n maxRequestAccessDuration: 'PT3H' // Critical: Minimal required port configuration for JIT\n }\n ]\n }\n ]\n }\n}\n```", + "Other": "1. In the Azure portal, go to Microsoft Defender for Cloud\n2. Select Workload protections > Just-in-time VM access\n3. Open the Not configured tab, select the VM, and click Enable JIT on VMs\n4. Keep the default port (22 for Linux or 3389 for Windows) and click Save", + "Terraform": "```hcl\n# Enable JIT by creating a Security Center JIT policy for the VM\nresource \"azurerm_security_center_jit_network_access_policy\" \"\" {\n name = \"default\"\n location = \"\"\n resource_group_name = \"\"\n\n virtual_machines {\n id = \"\" # Critical: VM ID included in the JIT policy enables JIT for this VM\n\n ports {\n number = 22\n protocol = \"*\"\n allowed_source_address_prefixes = [\"*\"]\n max_request_access_duration = \"PT3H\" # Critical: Minimal port config required by JIT\n }\n }\n}\n```" }, "Recommendation": { - "Text": "Enable Just-in-Time (JIT) network access for your Microsoft Azure virtual machines using the Azure Portal under Security Center > Just-in-time VM access.", - "Url": "https://docs.microsoft.com/en-us/azure/security-center/security-center-just-in-time?tabs=jit-config-asc%2Cjit-request-asc" + "Text": "Enable **JIT network access** and apply **least privilege** and **zero trust**:\n- keep admin ports closed by default\n- approve only specific IPs, minimal ports (e.g., `22`, `3389`), and short windows\n- favor **private access** (VPN, Bastion)\n- layer controls (**defense in depth**) and audit access requests", + "Url": "https://hub.prowler.com/check/vm_jit_access_enabled" } }, - "Categories": [], + "Categories": [ + "internet-exposed" + ], "DependsOn": [], "RelatedTo": [], "Notes": "JIT access can only be enabled via the Azure Portal. Ensure Security Center standard pricing tier for servers is enabled." diff --git a/prowler/providers/azure/services/vm/vm_linux_enforce_ssh_authentication/vm_linux_enforce_ssh_authentication.metadata.json b/prowler/providers/azure/services/vm/vm_linux_enforce_ssh_authentication/vm_linux_enforce_ssh_authentication.metadata.json index 75dcfe9d28..e2ec0ba32c 100644 --- a/prowler/providers/azure/services/vm/vm_linux_enforce_ssh_authentication/vm_linux_enforce_ssh_authentication.metadata.json +++ b/prowler/providers/azure/services/vm/vm_linux_enforce_ssh_authentication/vm_linux_enforce_ssh_authentication.metadata.json @@ -1,30 +1,36 @@ { "Provider": "azure", "CheckID": "vm_linux_enforce_ssh_authentication", - "CheckTitle": "Ensure SSH key authentication is enforced on Linux-based Virtual Machines", + "CheckTitle": "Linux Virtual Machine has password authentication disabled (SSH key authentication enforced)", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", - "ResourceIdTemplate": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}", + "ResourceIdTemplate": "", "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Ensure that Azure Linux-based virtual machines are configured to use SSH keys by disabling password authentication.", - "Risk": "Allowing password-based SSH authentication increases the risk of brute-force attacks and unauthorized access. Enforcing SSH key authentication ensures only users with the private key can access the VM.", - "RelatedUrl": "https://docs.microsoft.com/en-us/azure/virtual-machines/linux/create-ssh-keys-detailed", + "Description": "**Azure Linux virtual machines** are assessed for SSH configuration where `disablePasswordAuthentication` is set to `true`, allowing only **public key authentication** and disallowing interactive passwords.", + "Risk": "With **password-based SSH**, attackers can run brute-force or password-spray campaigns. A successful login grants remote shell, enabling command execution, data exfiltration, and lateral movement, degrading **confidentiality** and **integrity**.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/ssh-authentication-type.html", + "https://learn.microsoft.com/en-us/azure/virtual-machines/linux/create-ssh-keys-detailed" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/ssh-authentication-type.html", - "Terraform": "" + "NativeIaC": "```bicep\n// Bicep snippet to enforce SSH key authentication on a Linux VM\nresource linuxVm 'Microsoft.Compute/virtualMachines@2024-03-01' = {\n name: ''\n location: ''\n properties: {\n osProfile: {\n linuxConfiguration: {\n disablePasswordAuthentication: true // CRITICAL: Disables password-based SSH; enforces SSH key authentication\n }\n }\n }\n}\n```", + "Other": "1. In Azure Portal, go to your Linux VM > Settings > Export template\n2. Click Edit template\n3. Find properties.osProfile.linuxConfiguration and set disablePasswordAuthentication to true\n4. Ensure an SSH public key is provided (adminPassword must be absent)\n5. Click Save, then Review + create to deploy the update", + "Terraform": "```hcl\n# Minimal Terraform to enforce SSH key authentication on a Linux VM\nresource \"azurerm_linux_virtual_machine\" \"\" {\n name = \"\"\n resource_group_name = \"\"\n location = \"\"\n size = \"Standard_B1s\"\n network_interface_ids = [\"\"]\n admin_username = \"azureuser\"\n\n disable_password_authentication = true # CRITICAL: Disables password-based SSH; enforces SSH key authentication\n\n admin_ssh_key { # Required when password auth is disabled\n username = \"azureuser\"\n public_key = \"\"\n }\n\n os_disk {\n caching = \"ReadWrite\"\n storage_account_type = \"Standard_LRS\"\n }\n\n source_image_reference {\n publisher = \"Canonical\"\n offer = \"0001-com-ubuntu-server-focal\"\n sku = \"20_04-lts\"\n version = \"latest\"\n }\n}\n```" }, "Recommendation": { - "Text": "Recreate Linux VMs with SSH key authentication enabled and password authentication disabled.", - "Url": "https://docs.microsoft.com/en-us/azure/virtual-machines/linux/create-ssh-keys-detailed" + "Text": "Enforce **key-only SSH** by setting `disablePasswordAuthentication` to `true` and disallowing OS password logins. Use strong, passphrase-protected keys with rotation; restrict SSH via NSGs and private access or **Azure Bastion**; enable JIT; and apply **least privilege**.", + "Url": "https://hub.prowler.com/check/vm_linux_enforce_ssh_authentication" } }, - "Categories": [], + "Categories": [ + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/vm/vm_scaleset_associated_with_load_balancer/vm_scaleset_associated_with_load_balancer.metadata.json b/prowler/providers/azure/services/vm/vm_scaleset_associated_with_load_balancer/vm_scaleset_associated_with_load_balancer.metadata.json index 9e4b4ed95b..2a5f197734 100644 --- a/prowler/providers/azure/services/vm/vm_scaleset_associated_with_load_balancer/vm_scaleset_associated_with_load_balancer.metadata.json +++ b/prowler/providers/azure/services/vm/vm_scaleset_associated_with_load_balancer/vm_scaleset_associated_with_load_balancer.metadata.json @@ -1,30 +1,38 @@ { "Provider": "azure", "CheckID": "vm_scaleset_associated_with_load_balancer", - "CheckTitle": "VM Scale Set Is Associated With Load Balancer", + "CheckTitle": "Virtual Machine Scale Set is associated with a load balancer backend pool", "CheckType": [], "ServiceName": "vm", - "SubServiceName": "scaleset", - "ResourceIdTemplate": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}", + "SubServiceName": "", + "ResourceIdTemplate": "", "Severity": "medium", - "ResourceType": "Microsoft.Compute/virtualMachineScaleSets", + "ResourceType": "microsoft.compute/virtualmachinescalesets", "ResourceGroup": "compute", - "Description": "Ensure that your Azure virtual machine scale sets are using load balancers for traffic distribution.", - "Risk": "Without load balancer integration, Azure virtual machine scale sets may experience reduced availability and potential service disruptions during traffic spikes or instance failures, leading to degraded user experience and potential business impact.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-network/network-overview", + "Description": "**Azure VM scale sets** are associated with at least one **load balancer backend pool**.\n\nThe evaluation looks for a backend pool link on each scale set's network configuration.", + "Risk": "Without a load balancer, traffic targets instances directly, bypassing health-based distribution. This degrades **availability** (overloads, no failover) and **reliability** (dropped sessions, uneven scaling) and can amplify **DoS** impact by concentrating flows on fewer nodes, increasing outage risk.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/virtual-network/network-overview", + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/associated-load-balancers.html", + "https://learn.microsoft.com/ms-my/azure/load-balancer/load-balancer-multiple-virtual-machine-scale-set?tabs=azureportal", + "https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-overview" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/associated-load-balancers.html", - "Terraform": "" + "CLI": "az vmss update --resource-group --name --add virtualMachineProfile.networkProfile.networkInterfaceConfigurations[0].ipConfigurations[0].loadBalancerBackendAddressPools '{\"id\":\"/subscriptions//resourceGroups//providers/Microsoft.Network/loadBalancers//backendAddressPools/\"}'", + "NativeIaC": "```bicep\n// Associate VMSS with a Load Balancer backend pool\nresource vmss 'Microsoft.Compute/virtualMachineScaleSets@2023-09-01' = {\n name: ''\n location: resourceGroup().location\n properties: {\n virtualMachineProfile: {\n networkProfile: {\n networkInterfaceConfigurations: [\n {\n name: 'nic'\n properties: {\n ipConfigurations: [\n {\n name: 'ipcfg'\n properties: {\n loadBalancerBackendAddressPools: [\n { id: '' } // CRITICAL: attach VMSS NIC IP config to LB backend pool\n ]\n }\n }\n ]\n }\n }\n ]\n }\n }\n }\n}\n```", + "Other": "1. In Azure Portal, go to Load balancers > select \n2. Under Settings, open Backend pools and select the target backend pool\n3. Click Add > IP configurations\n4. Choose Virtual machine scale set, select and its IP configuration\n5. Click Add, then Save to attach the scale set to the backend pool", + "Terraform": "```hcl\n# Attach VMSS to an existing Load Balancer backend pool\nresource \"azurerm_linux_virtual_machine_scale_set\" \"\" {\n name = \"\"\n resource_group_name = \"\"\n location = \"\"\n sku = \"Standard_DS1_v2\"\n instances = 1\n\n admin_username = \"azureuser\"\n disable_password_authentication = true\n admin_ssh_key {\n username = \"azureuser\"\n public_key = \"\"\n }\n\n source_image_reference {\n publisher = \"Canonical\"\n offer = \"0001-com-ubuntu-server-jammy\"\n sku = \"22_04-lts\"\n version = \"latest\"\n }\n\n network_interface {\n name = \"nic\"\n primary = true\n ip_configuration {\n name = \"ipcfg\"\n primary = true\n subnet_id = \"\"\n load_balancer_backend_address_pool_ids = [\"\"] # CRITICAL: associates VMSS with LB backend pool\n }\n }\n}\n```" }, "Recommendation": { - "Text": "Attach a load balancer to your Azure virtual machine scale set to ensure high availability and optimal traffic distribution.", - "Url": "https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-overview" + "Text": "Associate VM scale sets with a **Standard Load Balancer** backend pool to enforce health-probed, even distribution and seamless failover.\n\nDesign for **high availability**: run multiple instances across zones, enable autoscale, and apply **defense in depth** with limited exposure and NSG controls. *Prefer SKU `Standard` over legacy Basic.*", + "Url": "https://hub.prowler.com/check/vm_scaleset_associated_with_load_balancer" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/vm/vm_scaleset_not_empty/vm_scaleset_not_empty.metadata.json b/prowler/providers/azure/services/vm/vm_scaleset_not_empty/vm_scaleset_not_empty.metadata.json index a2012c7696..af45f81ae0 100644 --- a/prowler/providers/azure/services/vm/vm_scaleset_not_empty/vm_scaleset_not_empty.metadata.json +++ b/prowler/providers/azure/services/vm/vm_scaleset_not_empty/vm_scaleset_not_empty.metadata.json @@ -1,30 +1,36 @@ { "Provider": "azure", "CheckID": "vm_scaleset_not_empty", - "CheckTitle": "Check for Empty Virtual Machine Scale Sets", + "CheckTitle": "Virtual Machine Scale Set has at least one VM instance", "CheckType": [], "ServiceName": "vm", - "SubServiceName": "scaleset", - "ResourceIdTemplate": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}", - "Severity": "low", - "ResourceType": "Microsoft.Compute/virtualMachineScaleSets", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", + "ResourceType": "microsoft.compute/virtualmachinescalesets", "ResourceGroup": "compute", - "Description": "Identify and remove empty virtual machine scale sets from your Azure cloud account.", - "Risk": "Empty virtual machine scale sets may incur unnecessary costs and complicate cloud resource management, impacting cost optimization and compliance.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview", + "Description": "**Azure VM scale sets** with `0` VM instances are identified as **empty**.", + "Risk": "Orphaned scale sets degrade governance and can hide **stale autoscale** or permissive identities. If reactivated, they may launch VMs from **outdated images**, exposing vulnerable services and enabling lateral movement, impacting **confidentiality** and **availability**. They also create inventory sprawl and unnecessary spend.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview", + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/empty-vm-scale-sets.html" + ], "Remediation": { "Code": { - "CLI": "az vmss delete --name --resource-group ", + "CLI": "az vmss scale --resource-group --name --new-capacity 1", "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/empty-vm-scale-sets.html", - "Terraform": "" + "Other": "1. In Azure Portal, go to Virtual machine scale sets and select \n2. Under Settings, click Scaling\n3. Set Instance count to 1\n4. Click Save", + "Terraform": "```hcl\n# Patch the scale set to have at least one instance\nresource \"azapi_update_resource\" \"\" {\n type = \"Microsoft.Compute/virtualMachineScaleSets@2024-03-01\"\n resource_id = \"\"\n\n body = jsonencode({\n sku = {\n capacity = 1 # Critical: ensures the scale set has at least one VM instance\n }\n })\n}\n```" }, "Recommendation": { - "Text": "Remove empty Azure virtual machine scale sets to optimize costs and simplify management.", - "Url": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/empty-vm-scale-sets.html" + "Text": "Decommission empty scale sets or consolidate capacity. Apply **resource lifecycle** and **governance policies** to prevent drift; require tagging and owners, review regularly. Manage capacity through **IaC**, enforce **least privilege** on scale set identities, and use change control to avoid unintended autoscale activations. *If retained temporarily*, document purpose and review date.", + "Url": "https://hub.prowler.com/check/vm_scaleset_not_empty" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/vm/vm_sufficient_daily_backup_retention_period/vm_sufficient_daily_backup_retention_period.metadata.json b/prowler/providers/azure/services/vm/vm_sufficient_daily_backup_retention_period/vm_sufficient_daily_backup_retention_period.metadata.json index 63809ce7ae..b668c8fdfc 100644 --- a/prowler/providers/azure/services/vm/vm_sufficient_daily_backup_retention_period/vm_sufficient_daily_backup_retention_period.metadata.json +++ b/prowler/providers/azure/services/vm/vm_sufficient_daily_backup_retention_period/vm_sufficient_daily_backup_retention_period.metadata.json @@ -1,30 +1,36 @@ { "Provider": "azure", "CheckID": "vm_sufficient_daily_backup_retention_period", - "CheckTitle": "Ensure there is a sufficient daily backup retention period configured for Azure virtual machines.", + "CheckTitle": "Virtual Machine has a backup policy with a daily retention period meeting the configured minimum", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "medium", - "ResourceType": "Microsoft.Compute/virtualMachines", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "Ensure there is a sufficient daily backup retention period configured for Azure virtual machines.", - "Risk": "Having an optimal daily backup retention period for your Azure virtual machines will enforce your backup strategy to follow the best practices as specified in the compliance regulations promoted by your organization. Retaining VM backups for a longer period of time will allow you to handle more efficiently your data restoration process in the event of a failure.", - "RelatedUrl": "https://docs.microsoft.com/en-us/azure/backup/backup-azure-vms-introduction", + "Description": "**Azure virtual machines** are evaluated for a backup policy in a Recovery Services vault with a **daily retention** period that meets the configured minimum. VMs lacking protection or using a shorter retention window are identified for review.", + "Risk": "**Insufficient or missing VM backups** weaken **availability** and **integrity**. Short retention reduces recovery points, limiting rollback after **ransomware**, accidental deletion, or faulty changes. This increases RPO, extends RTO, and can force rebuilds, causing data loss and downtime.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/azure/VirtualMachines/sufficient-backup-retention-period.html", + "https://learn.microsoft.com/en-us/azure/backup/backup-azure-vms-introduction" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/VirtualMachines/sufficient-backup-retention-period.html", - "Terraform": "" + "NativeIaC": "```bicep\n// Create/ensure a VM backup policy with daily retention >= minimum\nresource rv 'Microsoft.RecoveryServices/vaults@2023-01-01' existing = {\n name: ''\n}\n\nresource vmPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies@2023-02-01' = {\n name: '${rv.name}/'\n properties: {\n backupManagementType: 'AzureIaasVM'\n schedulePolicy: {\n schedulePolicyType: 'SimpleSchedulePolicyV2'\n scheduleRunFrequency: 'Daily'\n scheduleRunTimes: ['2020-01-01T23:00:00Z']\n }\n retentionPolicy: {\n retentionPolicyType: 'LongTermRetentionPolicy'\n dailySchedule: {\n retentionTimes: ['2020-01-01T23:00:00Z']\n retentionDuration: {\n count: 7 // CRITICAL: sets daily retention to at least the minimum required days\n durationType: 'Days' // explains the unit\n }\n }\n }\n }\n}\n```", + "Other": "1. In Azure portal, go to Recovery Services vault \n2. Select Backup policies > Azure Virtual Machine > Edit (or Create new)\n3. Set Daily retention to at least 7 days and Save\n4. Go to Backup items > Azure Virtual Machine\n5. If the VM is unprotected: click Backup, select the policy from step 3, and Enable\n6. If the VM is already protected with an insufficient policy: select the VM > Change Policy > choose the policy from step 3 > Save", + "Terraform": "```hcl\n# Backup policy with sufficient daily retention\nresource \"azurerm_backup_policy_vm\" \"\" {\n name = \"\"\n resource_group_name = \"\"\n recovery_vault_name = \"\"\n\n backup {\n frequency = \"Daily\"\n time = \"23:00\"\n }\n\n retention_daily {\n count = 7 # CRITICAL: ensures daily retention meets minimum required days\n }\n}\n\n# Protect the VM with the compliant policy\nresource \"azurerm_backup_protected_vm\" \"\" {\n resource_group_name = \"\"\n recovery_vault_name = \"\"\n source_vm_id = \"\"\n backup_policy_id = azurerm_backup_policy_vm..id # CRITICAL: applies the policy to the VM\n}\n```" }, "Recommendation": { - "Text": "Set the daily backup retention period for each VM's backup policy to meet or exceed your organization's minimum requirement.", - "Url": "https://docs.microsoft.com/en-us/azure/backup/backup-azure-vms-introduction" + "Text": "Enforce backup policies that provide **daily retention** aligned to business RPO/RTO for every VM. Apply **defense in depth**: isolate backups in a vault, enable immutability/soft delete, limit changes with **least privilege** and MFA, and regularly test restores. Use tiered retention (daily/weekly/monthly/yearly) based on data criticality.", + "Url": "https://hub.prowler.com/check/vm_sufficient_daily_backup_retention_period" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled.metadata.json b/prowler/providers/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled.metadata.json index c68c4ec6ee..b53ac0ac78 100644 --- a/prowler/providers/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled.metadata.json +++ b/prowler/providers/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled.metadata.json @@ -1,30 +1,35 @@ { "Provider": "azure", "CheckID": "vm_trusted_launch_enabled", - "CheckTitle": "Ensure Trusted Launch is enabled on Virtual Machines", + "CheckTitle": "Virtual Machine has Trusted Launch with Secure Boot and vTPM enabled", "CheckType": [], "ServiceName": "vm", "SubServiceName": "", "ResourceIdTemplate": "", - "Severity": "high", - "ResourceType": "Microsoft.Compute/virtualMachines", + "Severity": "medium", + "ResourceType": "microsoft.compute/virtualmachines", "ResourceGroup": "compute", - "Description": "When Secure Boot and vTPM are enabled together, they provide a strong foundation for protecting your VM from boot attacks. For example, if an attacker attempts to replace the bootloader with a malicious version, Secure Boot will prevent the VM from booting. If the attacker is able to bypass Secure Boot and install a malicious bootloader, vTPM can be used to detect the intrusion and alert you.", - "Risk": "Secure Boot and vTPM work together to protect your VM from a variety of boot attacks, including bootkits, rootkits, and firmware rootkits. Not enabling Trusted Launch in Azure VM can lead to increased vulnerability to rootkits and boot-level malware, reduced ability to detect and prevent unauthorized changes to the boot process, and a potential compromise of system integrity and data security.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machines/trusted-launch-existing-vm?tabs=portal", + "Description": "**Azure VMs** are evaluated for **Trusted Launch** with both **Secure Boot** and **vTPM** enabled.\n\nIdentifies VMs not set to `TrustedLaunch` or missing `secureBootEnabled` and `vTpmEnabled` together.", + "Risk": "Missing **Trusted Launch** weakens boot-chain integrity. Attackers can persist via bootkits/rootkits, bypass OS controls, steal secrets, and tamper with drivers. Loss of attestation reduces detection, risking **integrity**, **confidentiality**, and **availability** through stealthy, hard-to-remediate compromises.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/virtual-machines/trusted-launch" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "az vm update --resource-group --name --security-type TrustedLaunch --enable-secure-boot true --enable-vtpm true", + "NativeIaC": "```bicep\n// Enables Trusted Launch with Secure Boot and vTPM on the VM\nresource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = {\n name: ''\n location: ''\n properties: {\n securityProfile: {\n securityType: 'TrustedLaunch' // Critical: sets VM security type to Trusted Launch\n uefiSettings: {\n secureBootEnabled: true // Critical: enables Secure Boot\n vTpmEnabled: true // Critical: enables vTPM\n }\n }\n }\n}\n```", + "Other": "1. In Azure Portal, open the VM and click Stop to deallocate it\n2. Go to Settings > Configuration\n3. Under Security type, select Trusted launch\n4. Check Secure Boot and vTPM\n5. Click Save\n6. Start the VM from the Overview page", + "Terraform": "```hcl\n# Patch the existing VM to enable Trusted Launch with Secure Boot and vTPM\nresource \"azapi_update_resource\" \"\" {\n type = \"Microsoft.Compute/virtualMachines@2022-11-01\"\n resource_id = \"\"\n\n body = jsonencode({\n properties = {\n securityProfile = {\n securityType = \"TrustedLaunch\" # Critical: sets VM security type to Trusted Launch\n uefiSettings = {\n secureBootEnabled = true # Critical: enables Secure Boot\n vTpmEnabled = true # Critical: enables vTPM\n }\n }\n }\n })\n}\n```" }, "Recommendation": { - "Text": "1. Go to Virtual Machines 2. For each VM, under Settings, click on Configuration on the left blade 3. Under Security Type, select 'Trusted Launch Virtual Machines' 4. Make sure Enable Secure Boot & Enable vTPM are checked 5. Click on Apply.", - "Url": "https://learn.microsoft.com/en-us/azure/virtual-machines/trusted-launch-existing-vm?tabs=portal#enable-trusted-launch-on-existing-vm" + "Text": "Adopt **defense in depth**: enable **Trusted Launch** with **Secure Boot** and **vTPM** on Gen2 VMs. Standardize on images with signed boot components and use supported sizes/OS. Enforce **least privilege** for administrators and enable attestation monitoring to prevent and detect boot-level tampering.", + "Url": "https://hub.prowler.com/check/vm_trusted_launch_enabled" } }, - "Categories": [], + "Categories": [ + "node-security" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Secure Boot and vTPM are not currently supported for Azure Generation 1 VMs. IMPORTANT: Before enabling Secure Boot and vTPM on a Generation 2 VM which does not already have both enabled, it is highly recommended to create a restore point of the VM prior to remediation."