This check flags Azure subscriptions where Microsoft Defender for App Service is turned off, leaving your web apps and APIs without runtime threat detection. Enable the App Services Defender plan with a single CLI command or an Azure Policy to fix it across all subscriptions.
App Service is where a lot of Azure workloads actually live: customer-facing web apps, internal portals, REST APIs, and webhook receivers. Because these resources are reachable over the public internet by default, they are a constant target for scanners, credential stuffing, and exploitation of known framework vulnerabilities. Microsoft Defender for App Service exists to watch that traffic and the app runtime for signs of compromise. When it is disabled, you lose that visibility entirely.
The defender_appservices check looks at the Microsoft Defender for Cloud pricing configuration on each Azure subscription and reports any subscription where the AppServices plan is set to Free rather than Standard.
What this check detects
Microsoft Defender for Cloud is organized into per-resource-type plans. Each plan can be set to either the Free tier (which gives you the basic Cloud Security Posture Management features) or the Standard tier (which turns on the paid, workload-specific threat protection). This check inspects the App Service plan specifically.
If the result comes back as Free, Defender for App Service is not actively protecting your web apps in that subscription. The check is binary and scoped to the subscription, so a subscription with twenty App Service instances and a subscription with zero will both report the same finding when the plan is off.
Note: Microsoft renamed "Azure Security Center" to "Microsoft Defender for Cloud" and "Azure Defender" to the per-plan "Microsoft Defender for X" naming. In the CLI and APIs you will still see the old resource names like pricings and the plan name AppServices.
Why it matters
App Service runs your code on a managed platform, but the platform does not stop application-layer attacks for you. Defender for App Service analyzes the telemetry that App Service already collects, including HTTP logs, the internal process behavior, and the worker environment, then correlates it against known attack patterns. Without it, the following classes of activity go unnoticed:
- Web shell uploads. Attackers who gain a foothold often drop a web shell to maintain access. Defender detects known web shell signatures and anomalous file execution from the wwwroot directory.
- Exploitation attempts against your stack. Probing for known CVEs in PHP, .NET, Node, or the frameworks you run shows up as suspicious request patterns.
- Outbound connections to known-bad infrastructure. If a compromised app starts beaconing to a command-and-control server, Defender flags the connection.
- Dangling DNS and subdomain takeover risk. Defender surfaces App Service hostnames that have been deleted but still have DNS records pointing at them, a common takeover vector.
The business impact is straightforward. A compromised public web app is one of the most common entry points into a cloud environment. From there an attacker can read the app's managed identity token, reach connected databases, and pivot. Catching the initial web shell or exploitation attempt early is the difference between a contained incident and a breach disclosure.
Warning: Defender for App Service is a paid plan, billed per App Service instance per hour. Enabling it across a subscription with many apps has a real cost, so review the current pricing in the Defender for Cloud portal before flipping it on everywhere. The cost is usually small relative to the resources it protects, but it is not zero.
How to fix it
You can enable the plan from the portal, the Azure CLI, or infrastructure as code. The change is non-disruptive: it does not restart your apps or alter their configuration. It only turns on monitoring.
Option 1: Azure Portal
- Open Microsoft Defender for Cloud in the Azure portal.
- Go to Environment settings and select the subscription you want to fix.
- In the Defender plans view, find the App Service row.
- Toggle the plan from Off to On.
- Click Save.
Option 2: Azure CLI
Set the App Services pricing tier to Standard for the current subscription:
az security pricing create \
--name AppServices \
--tier Standard
Confirm the change took effect:
az security pricing show \
--name AppServices \
--query "pricingTier" \
--output tsv
You should see Standard returned.
To roll this out across every subscription you can access, loop through them:
for sub in $(az account list --query "[].id" -o tsv); do
az account set --subscription "$sub"
echo "Enabling Defender for App Service on $sub"
az security pricing create --name AppServices --tier Standard
done
Tip: Run the loop above first with az security pricing show instead of create to audit which subscriptions are already covered. That gives you an accurate cost estimate before you commit to enabling it everywhere.
Option 3: Terraform
If you manage Azure with Terraform, declare the plan so it stays enabled and any manual drift gets corrected on the next apply:
resource "azurerm_security_center_subscription_pricing" "app_service" {
tier = "Standard"
resource_type = "AppServices"
}
Option 4: Bicep
resource appServicePricing 'Microsoft.Security/pricings@2023-01-01' = {
name: 'AppServices'
properties: {
pricingTier: 'Standard'
}
}
How to prevent it from happening again
Enabling the plan once is easy. Keeping it enabled across new subscriptions and stopping someone from disabling it is the harder part. Azure Policy handles both.
Deploy a built-in policy with DeployIfNotExists
Microsoft ships a built-in policy that configures Defender for App Service automatically on any subscription assigned to it. Assigning it at the management group level means every current and future subscription underneath inherits the setting.
az policy assignment create \
--name "enable-defender-appservice" \
--display-name "Enable Defender for App Service" \
--scope "/providers/Microsoft.Management/managementGroups/" \
--policy "b40e7bcd-a1e5-47fe-b9cf-2f534d0bfb7d" \
--location eastus \
--mi-system-assigned \
--role "Security Admin"
Because this is a DeployIfNotExists policy, it needs a managed identity with the Security Admin role to perform the remediation. After assigning it, create a remediation task to bring existing non-compliant subscriptions into line:
az policy remediation create \
--name "remediate-defender-appservice" \
--policy-assignment "enable-defender-appservice"
Note: The built-in policy definition ID for "Azure Defender for App Service should be enabled" can change. Confirm the current ID with az policy definition list --query "[?contains(displayName, 'App Service should be enabled')].name" before assigning.
Add a CI/CD gate
If your subscriptions are provisioned through pipelines, add a check after subscription creation that verifies the plan before the pipeline reports success:
tier=$(az security pricing show --name AppServices --query "pricingTier" -o tsv)
if [ "$tier" != "Standard" ]; then
echo "FAIL: Defender for App Service is not enabled on this subscription"
exit 1
fi
echo "PASS: Defender for App Service is enabled"
Lensix re-runs the defender_appservices check on every scan, so even outside a pipeline you get an alert the moment a subscription drifts back to the Free tier.
Best practices
- Enable the full Defender suite, not just App Service. App Service rarely runs in isolation. Pair it with Defender for Servers, Defender for Containers, Defender for Storage, and Defender for Key Vault so an attacker who lands on one resource cannot move laterally undetected.
- Route Defender alerts somewhere a human reads. Detection only helps if someone acts on it. Configure Defender for Cloud to forward high-severity alerts to your SIEM or an on-call channel rather than letting them sit in the portal.
- Restrict App Service network exposure. Defender is a safety net, not a substitute for reducing attack surface. Put public apps behind a Web Application Firewall via Application Gateway or Front Door, and use access restrictions or private endpoints for internal-only apps.
- Use managed identities, not embedded secrets. Many App Service compromises escalate because connection strings or keys sit in app settings. Managed identities remove those secrets, and Defender will flag suspicious use of the identity token if one is stolen.
- Govern at the management group level. Set the policy once at the top of your hierarchy so new subscriptions are protected from the moment they exist, instead of relying on someone remembering to enable it.
Tip: Combine the DeployIfNotExists policy with a separate Audit policy that reports any subscription where someone manually downgraded a Defender plan. The deploy policy fixes drift on its schedule, and the audit policy gives you an immediate compliance signal in between remediation runs.
Defender for App Service is one of the lowest-effort, highest-value security controls you can turn on in Azure. The fix is a single setting, the risk it covers is one of the most common cloud breach paths, and a policy assignment keeps it enforced forever. Flip it on, govern it centrally, and let Lensix tell you if it ever slips.

