Back to Checks
azure

SQL server has Vulnerability Assessment enabled and scan report recipients configured

sqlserver_va_scan_reports_configured
Service: sqlserverSeverity: medium
OfficialBuilt-inVerified
Categories:vulnerabilities
Resource Type:microsoft.sql/servers

Azure SQL Server vulnerability assessment uses recurring scans and emails results to designated recipients. This evaluates that VA is enabled and that Send scan reports to (or subscription admin notifications) is configured so scan reports are delivered.

Risk

If VA reports aren't sent to responsible owners, findings can be missed, delaying fixes. Attackers may exploit misconfigurations, excessive permissions, or outdated settings, leading to data exposure (C), unauthorized changes (I), and potential service disruption (A).

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks sqlserver_va_scan_reports_configured

Recommendation

Enable Vulnerability Assessment, keep recurring scans active, and configure Send scan reports to with accountable security owners or subscription admins. Integrate notifications with central alerting, apply least privilege to recipients, and enforce SLAs to triage and remediate findings promptly.

Remediation

CLI

az rest --method PUT --url "https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Sql/servers/<SERVER_NAME>/vulnerabilityAssessments/Default?api-version=2023-08-01-preview" --body '{"properties":{"storageContainerPath":"https://<STORAGE_ACCOUNT>.blob.core.windows.net/<CONTAINER>","storageAccountAccessKey":"<STORAGE_KEY>","recurringScans":{"isEnabled":true,"emailSubscriptionAdmins":true,"emails":["<EMAIL_ADDRESS>"]}}}'

Terraform

# Enable VA (classic) on a SQL Server and configure recipients
resource "azurerm_mssql_server_vulnerability_assessment" "<example_resource_name>" {
  server_id                = "<example_resource_id>"
  storage_container_path   = "https://<example_storage_account>.blob.core.windows.net/<example_container>" # CRITICAL: enables VA classic by setting storage container
  storage_account_access_key = "<example_storage_key>"

  recurring_scans {
    enabled                   = true
    email_subscription_admins = true # CRITICAL: configures scan report recipients (subscription admins)
  }
}

NativeIaC

// Configure VA (classic) on a SQL Server and set recipients
resource sqlServer 'Microsoft.Sql/servers@2021-11-01' existing = {
  name: '<example_resource_name>'
}

resource va 'Microsoft.Sql/servers/vulnerabilityAssessments@2021-11-01' = {
  name: 'Default'
  parent: sqlServer
  properties: {
    storageContainerPath: 'https://<example_storage_account>.blob.core.windows.net/<example_container>' // CRITICAL: enables VA classic by setting storage container
    storageAccountAccessKey: '<example_storage_key>'
    recurringScans: {
      isEnabled: true
      emailSubscriptionAdmins: true // CRITICAL: configures scan report recipients (subscription admins)
    }
  }
}

Other

1In Azure Portal, go to SQL servers and select <your server>
2Under Security, open Vulnerability assessment
3Select a Storage account and Container, then Save
4In Recurring scans, turn On and enable Send to subscription admins (or add at least one email)
5Save

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.sqlserver.sqlserver_client import sqlserver_client


class sqlserver_va_scan_reports_configured(Check):
    def execute(self) -> Check_Report_Azure:
        findings = []
        for subscription, sql_servers in sqlserver_client.sql_servers.items():
            subscription_name = sqlserver_client.subscriptions.get(
                subscription, subscription
            )
            for sql_server in sql_servers:
                report = Check_Report_Azure(
                    metadata=self.metadata(), resource=sql_server
                )
                report.subscription = subscription
                report.status = "FAIL"
                report.status_extended = f"SQL Server {sql_server.name} from subscription {subscription_name} ({subscription}) has vulnerability assessment disabled."
                if (
                    sql_server.vulnerability_assessment
                    and sql_server.vulnerability_assessment.storage_container_path
                ):
                    report.status_extended = f"SQL Server {sql_server.name} from subscription {subscription_name} ({subscription}) has vulnerability assessment enabled but no scan reports configured."
                    if sql_server.vulnerability_assessment.recurring_scans and (
                        (
                            sql_server.vulnerability_assessment.recurring_scans.email_subscription_admins
                        )
                        or (
                            sql_server.vulnerability_assessment.recurring_scans.emails
                            and len(
                                sql_server.vulnerability_assessment.recurring_scans.emails
                            )
                            > 0
                        )
                    ):
                        report.status = "PASS"
                        report.status_extended = f"SQL Server {sql_server.name} from subscription {subscription_name} ({subscription}) has vulnerability assessment enabled and scan reports configured."
                findings.append(report)

        return findings