Back to Checks
azure

SQL Server has Vulnerability Assessment periodic recurring scans enabled

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

Azure SQL servers are evaluated for Vulnerability Assessment configuration and whether periodic recurring scans are scheduled (e.g., weekly) for the server and its databases.

Servers with Vulnerability Assessment missing or scans not scheduled are identified.

Risk

Without scheduled scans, new misconfigurations and vulnerable settings can persist unnoticed, weakening confidentiality and integrity. Attackers can exploit stale permissions, unsafe firewall rules, or unpatched features to read or alter data and pivot to other resources.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks sqlserver_va_periodic_recurring_scans_enabled

Recommendation

Enable recurring Vulnerability Assessment scans at server scope and ensure results are retained securely (express configuration or secured storage). Apply least privilege, maintain baselines, and promptly remediate findings. Automate alerting and periodic reviews as part of defense in depth and change management.

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":"<ACCESS_KEY>","recurringScans":{"isEnabled":true}}}'

Terraform

# Server VA with periodic recurring scans enabled
resource "azurerm_mssql_server_vulnerability_assessment" "<example_resource_name>" {
  server_security_alert_policy_id = "<example_resource_id>"
  storage_container_path          = "https://<example_storage_account>.blob.core.windows.net/<example_container>/" # Required so VA is configured
  storage_account_access_key      = "<example_access_key>"

  recurring_scans {
    enabled = true # CRITICAL: Enables periodic recurring scans
  }
}

NativeIaC

// Enable classic VA with recurring scans on an existing SQL Server
resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' existing = {
  name: '<example_resource_name>'
}

resource va 'Microsoft.Sql/servers/vulnerabilityAssessments@2023-08-01-preview' = {
  name: 'Default'
  parent: sqlServer
  properties: {
    storageContainerPath: 'https://<example_storage_account>.blob.core.windows.net/<example_container>/' // CRITICAL: Required so VA is considered configured
    storageAccountAccessKey: '<example_access_key>'
    recurringScans: {
      isEnabled: true // CRITICAL: Enables periodic recurring scans
    }
  }
}

Other

1In Azure Portal, go to SQL servers > select <your server>
2Under Security, open Vulnerability assessment (classic configuration)
3Set Storage container to an existing blob container and Save
4Turn Recurring scans to On
5Click Save to apply

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_periodic_recurring_scans_enabled(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 recurring scans."
                    if (
                        sql_server.vulnerability_assessment.recurring_scans
                        and sql_server.vulnerability_assessment.recurring_scans.is_enabled
                    ):
                        report.status = "PASS"
                        report.status_extended = f"SQL Server {sql_server.name} from subscription {subscription_name} ({subscription}) has periodic recurring scans enabled."
                findings.append(report)

        return findings