What it is
An Application Gateway whose sku.tier is Standard_v2 (or legacy Standard) instead of WAF_v2. It is a full layer-7 reverse proxy — it terminates TLS, reads every request, and routes it — but without the WAF tier there is no managed OWASP rule inspection. The one component in your architecture positioned to filter web attacks is configured not to.
Why it happens
The web application firewall on Application Gateway is not a feature you switch on later in a settings blade; it is a SKU tier chosen at creation, and Standard_v2 is the cheaper, more obvious pick. Teams choosing a SKU are usually thinking about load balancing and TLS termination, not attack inspection, so Standard wins and the decision is never revisited.
Sometimes it is a deliberate architecture call (inspection handled elsewhere, or a cost decision made with eyes open). But often nobody decided anything: the gateway works, traffic flows, and the absence of a WAF produces no error, no warning, and no line item to question. To be clear about severity: this is a defense-in-depth gap, not an open door by itself; an attacker still needs an exploitable backend. The gateway just does nothing to stop them looking for one.
What it costs / blast radius
Every request an attacker sends — SQL injection probes, XSS payloads, path traversal, known-CVE exploit attempts — is TLS-terminated, health-checked, and delivered to your backend with the same care as a paying customer's. Your applications' own input handling is the only defense layer left. (Azure behavior; authored assessment.)
The fix has a real, known price: at East US list price the WAF_v2 fixed charge is about $0.443/hour versus $0.246/hour for Standard_v2, roughly $144/month more before capacity units, which also bill higher ($0.0144 versus $0.008 per capacity-unit hour). (List prices; your region and contract may differ.) That is the honest trade: a modest, predictable spend for managed OWASP rule filtering at the edge. The upgrade is an in-place SKU change on v2, not a rebuild.
See it
resource appgw 'Microsoft.Network/applicationGateways@2024-05-01' = {
name: 'corp-appgw'
location: location
properties: {
sku: {
name: 'Standard_v2'
tier: 'Standard_v2' // no WAF: nothing inspects request payloads
}
// ...listeners, backend pools, routing rules
}
}resource wafPolicy 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-05-01' = {
name: 'corp-appgw-waf'
location: location
properties: {
policySettings: {
state: 'Enabled'
mode: 'Prevention' // see AZF-0091: Detection mode blocks nothing
}
managedRules: {
managedRuleSets: [
{
ruleSetType: 'OWASP'
ruleSetVersion: '3.2'
}
]
}
}
}
resource appgw 'Microsoft.Network/applicationGateways@2024-05-01' = {
name: 'corp-appgw'
location: location
properties: {
sku: {
name: 'WAF_v2'
tier: 'WAF_v2'
}
firewallPolicy: {
id: wafPolicy.id
}
// ...listeners, backend pools, routing rules unchanged
}
}How StratoLens helps
StratoLens flags every Application Gateway running a non-WAF SKU, automatically and continuously, across every subscription, inside your own tenant. Whether each one is a deliberate architecture choice or a decision nobody made becomes a question you can actually answer.