Azure VM data disk is encrypted with the default encryption key instead of ADE/CMK

ID

azure_managed_disc_encryption

Severity

high

Vendor

Azure

Resource

VM Disk

Tags

reachable

Description

Azure VM data disk should not be encrypted with the default encryption key.

By default, Server-Side Encryption (SSE) with platform-managed encryption keys, SSE with PMK, is used to encrypt Azure managed disks. With this option, Azure resource provider creates the keys, places them in secure storage, and retrieves them when needed, so the service has full access to the keys and the service has full control over the credential lifecycle management.

Instead of the default, it is recommended to use one of these other alternatives:

  • Customer Managed Key, SSE with CMK, whose difference with SSE-PMK is that the keys are stored in a customer managed key vault rather than a Microsoft managed key store.

  • SSE with Azure Disk Encryption, that depending on the OS uses Bitlocker (Windows) or DM-Crypt (Linux) to provide volume encryption for the OS and data disks of Azure virtual machines (VMs), while is integrated with Azure Key Vault.
    See Linux ADE or Windows ADE to know more about Azure Disk Encryption on those platforms.

Encryption does not impact the performance of managed disks and there is no additional cost for the encryption.

Examples

ARM

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [{
    "name": "bad", (1)
    "type": "Microsoft.Compute/disks",
    "location": "[resourceGroup().location]",
    "apiVersion": "2021-04-01",
    "tags": {
      "displayName": "Clone Disk"
    },
    "properties": {
      "creationData": {
        "createOption": "copy",
        "sourceUri": "[resourceId('Microsoft.Compute/snapshots', concat(variables('Front VM'), '-snapshot'))]"
      }
    }
  }]
}
1 is a VM Disk resource using default encryption key.

Terraform

resource "azurerm_managed_disk" "my_disk" {
  name                 = var.disk_name
  location             = var.location
  resource_group_name  = var.resource_group_name
  storage_account_type = var.storage_account_type
  create_option        = "Empty"
  disk_size_gb         = var.disk_size_gb

  # Flaw, encryption disabled
  encryption_settings {
    enabled = false (1)
  }

  tags = var.common_tags
}
1 Encryption is disabled.

Mitigation / Fix

Buildtime

ARM

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [{
    "name": "good", (1)
    "type": "Microsoft.Compute/disks",
    "location": "[resourceGroup().location]",
    "apiVersion": "2021-04-01",
    "tags": {
      "displayName": "Clone Disk"
    },
    "properties": {
      "creationData": {
        "createOption": "copy",
        "sourceUri": "[resourceId('Microsoft.Compute/snapshots', concat(variables('Front VM'), '-snapshot'))]"
      },
      "encryptionSettings": {
        "enabled": true,
        "diskEncryptionKey": {
           "sourceVault": {
             "id": "[parameters('keyVaultResourceID')]"
           },
          "secretUrl": "[parameters('keyVaultSecretUrl')]"
        },
        "keyEncryptionKey": {
          "sourceVault": {
            "id": "[parameters('kekVaultResourceID')]"
          },
          "keyUrl": "[parameters('kekUrl')]"
        }
      }
    }
  }]
}
1 set enabled flag to true and provide DiskEncryptionKey and optional KeyEncryptionKey to enable encryption.
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [{
    "name": "good",
    "type": "Microsoft.Compute/disks",
    "location": "[resourceGroup().location]",
    "apiVersion": "2021-04-01",
    "tags": {
      "displayName": "Clone Disk"
    },
    "properties": {
      "creationData": {
        "createOption": "copy",
        "sourceUri": "[resourceId('Microsoft.Compute/snapshots', concat(variables('Front VM'), '-snapshot'))]"
      },
      "encryptionSettingsCollection": {
        "enabled": true, (1)
        "encryptionSettings": {
          "diskEncryptionKey": {
            "sourceVault": {
              "id": "[parameters('keyVaultResourceID')]"
            },
            "secretUrl": "[parameters('keyVaultSecretUrl')]"
          },
          "keyEncryptionKey": {
            "sourceVault": {
              "id": "[parameters('kekVaultResourceID')]"
            },
            "keyUrl": "[parameters('kekUrl')]"
          }
        }
      }
    }
  }]
}
1 set enabled flag to true and provide DiskEncryptionKey and optional KeyEncryptionKey to enable encryption.

Terraform

resource "azurerm_managed_disk" "my_disk" {
  name                 = var.disk_name
  location             = var.location
  resource_group_name  = var.resource_group_name
  storage_account_type = var.storage_account_type
  create_option        = "Empty"
  disk_size_gb         = var.disk_size_gb

  # Flaw, encryption disabled
  encryption_settings {
    enabled = true (1)

    disk_encryption_key {
      secret_url      = azurerm_key_vault_secret.disk_enc_secret.id
      source_vault_id = azurerm_key_vault.vault.id
    }
    key_encryption_key {
      key_url         = azurerm_key_vault_key.disk_enc_key.id
      source_vault_id = azurerm_key_vault.vault.id
    }
  }

  tags = var.common_tags
}
1 Encryption enabled, disk_encryption_key and key_encryption_key configured.