Skip to main content
emnode
Compliance Medium severity MCSB LT-1

Microsoft Defender for Cloud · Azure SQL Database

All advanced threat protection types should be enabled in SQL server advanced data security settings

Written and reviewed by Emnode · Last reviewed

What does the recommendation "All advanced threat protection types should be enabled in SQL server advanced data security settings" check?

Flags an Azure SQL logical server where Advanced Threat Protection is part of Microsoft Defender for SQL but the set of detection types is not 'All', meaning one or more alert categories have been switched off so the threat-detection policy is left on 'None' or 'Custom'. The full set covers potential SQL injection, access from an unusual location or data centre, access from an unfamiliar principal or potentially harmful application, and brute-force SQL credential attempts. The control checks only that every type is active. It does not verify that the Microsoft Defender for SQL plan itself is enabled, that SQL Vulnerability Assessment is configured, that auditing is on, or that notification email addresses are populated. Those each have their own separate recommendations, so a passing result here does not imply the wider Defender posture is complete.

Why does "All advanced threat protection types should be enabled in SQL server advanced data security settings" matter?

Leaving even one detection type disabled creates a silent blind spot: the engine keeps running and the server still looks 'protected' on the summary tile, but alerts for the suppressed category are never raised. An attacker probing with SQL injection or grinding through brute-force logins can then operate without tripping any signal, and because nothing fires there is no record for the SOC to triage after the fact. The business consequence is a breach that is detected late or only by a third party, with the regulatory and customer-trust costs that late detection of a data exposure carries. Enabling all types restores full coverage at no extra cost, since the detections are already included in the Defender for SQL plan you are paying for.

How do I fix "All advanced threat protection types should be enabled in SQL server advanced data security settings"?

  1. Confirm Microsoft Defender for SQL is enabled on the server, then in the portal open the server's Security blade, select Microsoft Defender for Cloud, choose Configure, and under ADVANCED THREAT PROTECTION SETTINGS make sure no detection types are excluded so the policy resolves to 'All' rather than 'None' or 'Custom'.
  2. From the CLI, enable the setting at server scope with 'az sql server advanced-threat-protection-setting update -g <resource-group> -n <server> --state Enabled' (the server command exposes only --state, so do not pass a --disabled-alerts flag here); to clear any per-type exclusions left over from the deprecated 'az sql db threat-policy --disabled-alerts', use the current 'az sql db advanced-threat-protection-setting' command instead.
  3. Assign the matching built-in Azure Policy so new servers stay compliant, looking the definition up by display name rather than hardcoding a GUID: pid=$(az policy definition list --query "[?displayName=='All advanced threat protection types should be enabled in SQL server advanced data security settings'].name" -o tsv) then az policy assignment create --name atp-all-types --policy "$pid" --scope <scope>.

Remediation script · bash

# 1. Enable Advanced Threat Protection on every logical server (detection only, no blocking).
for row in $(az sql server list --query "[].{n:name,g:resourceGroup}" -o tsv | tr '\t' ','); do
  n=$(echo "$row" | cut -d',' -f1); g=$(echo "$row" | cut -d',' -f2)
  az sql server advanced-threat-protection-setting update -g "$g" -n "$n" --state Enabled
  echo "$n: advanced threat protection enabled"
done

# 2. Same for every SQL Managed Instance.
for row in $(az sql mi list --query "[].{n:name,g:resourceGroup}" -o tsv | tr '\t' ','); do
  n=$(echo "$row" | cut -d',' -f1); g=$(echo "$row" | cut -d',' -f2)
  az sql mi advanced-threat-protection-setting update -g "$g" -n "$n" --state Enabled
done

# 3. Turn on the Defender for Azure SQL plan for the whole subscription so new
#    databases are covered automatically (this is what carries the per-resource cost).
az security pricing create -n SqlServers --tier Standard

# 4. Enforce at scale via the supported built-in policy (looked up by display name,
#    never a hardcoded GUID). Do NOT assign the deprecated 'set to All' policy.
pid=$(az policy definition list \
  --query "[?displayName=='Configure Azure Defender to be enabled on SQL servers and SQL Managed Instances'].name" -o tsv)
az policy assignment create \
  --name enable-defender-sql \
  --policy "$pid" \
  --scope "/subscriptions/<subscription-id>"

Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure SQL Database.

Is "All advanced threat protection types should be enabled in SQL server advanced data security settings" a false positive?

A non-production server fronting a test database with no real data may be deliberately scoped to a narrow set of alert types to cut notification noise, which trips this control. That is a legitimate exception: document it and exempt the resource in Defender for Cloud rather than forcing 'All', but never carry the same exception across to any server that holds production or personal data.