Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
- App Configuration:
- Check that replica locations are in allowed regions by @BernieWhite.
[#3441](https://github.com/Azure/PSRule.Rules.Azure/issues/3441)
- Updated rules:
- Application Gateway Policy:
- Updated `Azure.AppGwWAF.RuleGroups` to use Microsoft Default Rule Set instead of legacy OWASP rule set by @BenjaminEngeset.
[#3553](https://github.com/Azure/PSRule.Rules.Azure/issues/3553)

## v1.46.0

Expand Down
127 changes: 116 additions & 11 deletions docs/en/rules/Azure.AppGwWAF.RuleGroups.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
reviewed: 2024-01-04
reviewed: 2025-10-28
severity: Critical
pillar: Security
category: Network security and containment
category: SE:06 Network controls
resource: Application Gateway
resourceType: Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AppGwWAF.RuleGroups/
Expand All @@ -12,25 +12,130 @@ online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AppGwW

## SYNOPSIS

Use recommended rule groups in Application Gateway Web Application Firewall (WAF) policies to protect back end resources.
Application Gateway WAF policies should include both Microsoft Default Rule Set and Bot Manager Rule Set to provide
comprehensive protection against web application threats and malicious bot traffic.

## DESCRIPTION

Application Gateway WAF policies support two main Rule Groups.
Application Gateway Web Application Firewall (WAF) policies require two managed rule sets to provide
comprehensive security coverage for web applications:

- OWASP - Application Gateway web application firewall (WAF) protects web applications from common vulnerabilities and exploits.
This is done through rules that are defined based on the OWASP core rule sets 3.2, 3.1, 3.0.
It is recommended to use the latest rule set.
- Bot protection - Enable a managed bot protection rule set to block or log requests from known malicious IP addresses.
- Microsoft Default Rule Set 2.1 or later.
- Microsoft Bot Manager Rule Set 1.0 or later.

The Microsoft Default Rule Set provides protection against the most common web application vulnerabilities and attacks.
This rule set is based on industry-standard security patterns and includes:

- Protection against OWASP Top 10 vulnerabilities.
- SQL injection attack prevention.
- Cross-site scripting (XSS) protection.
- Local file inclusion (LFI) and remote file inclusion (RFI) protection.
- Protocol violation detection.

The Bot Manager Rule Set provides automated protection against malicious bot traffic and includes:

- Known bad bot detection and blocking.
- Rate limiting for suspicious traffic patterns.
- Protection against automated attacks and scraping.
- Integration with Microsoft threat intelligence.

## RECOMMENDATION

Consider configuring Application Gateway WAF policy to use the recommended rule sets.
Consider using both Microsoft Default Rule Set and Microsoft Bot Manager Rule Set in your WAF policy
to ensure comprehensive protection against web attacks and malicious bot traffic.

## EXAMPLES

### Configure with Bicep

To deploy WAF policies that pass this rule:

- Add following managed rules sets by specifying the `properties.managedRules.managedRuleSets` property:
- Add the `Microsoft_DefaultRuleSet` version `2.1` or later.
- Add the `Microsoft_BotManagerRuleSet` version `1.0` or later.

For example:

```bicep
resource waf 'Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies@2024-10-01' = {
name: name
location: location
properties: {
managedRules: {
managedRuleSets: [
{
ruleSetType: 'Microsoft_DefaultRuleSet'
ruleSetVersion: '2.1'
}
{
ruleSetType: 'Microsoft_BotManagerRuleSet'
ruleSetVersion: '1.1'
}
]
}
policySettings: {
state: 'Enabled'
mode: 'Prevention'
}
}
}
```

<!-- external:avm avm/res/network/application-gateway-web-application-firewall-policy managedRules -->

### Configure with Azure template

To deploy WAF policies that pass this rule:

- Add following managed rules sets by specifying the `properties.managedRules.managedRuleSets` property:
- Add the `Microsoft_DefaultRuleSet` version `2.1` or later.
- Add the `Microsoft_BotManagerRuleSet` version `1.0` or later.

For example:

```json
{
"type": "Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies",
"apiVersion": "2024-10-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"properties": {
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.1"
},
{
"ruleSetType": "Microsoft_BotManagerRuleSet",
"ruleSetVersion": "1.1"
}
]
},
"policySettings": {
"state": "Enabled",
"mode": "Prevention"
}
}
}
```

## NOTES

This rule requires both rule sets to be configured at minimum version in the WAF policy's managed rules section.
The rule sets work together to provide layered security protection for your web applications.

- For `Microsoft_DefaultRuleSet` use version `2.1` or later.
- For `Microsoft_BotManagerRuleSet` use version `1.0` or later.

## LINKS

- [Best practices for endpoint security on Azure](https://learn.microsoft.com/azure/architecture/framework/security/design-network-endpoints)
- [SE:06 Network controls](https://learn.microsoft.com/azure/well-architected/security/networking)
- [Security: Level 2](https://learn.microsoft.com/azure/well-architected/security/maturity-model?tabs=level2)
- [Securing PaaS deployments](https://learn.microsoft.com/azure/security/fundamentals/paas-deployments#install-a-web-application-firewall)
- [Web Application Firewall CRS rule groups and rules](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules)
- [Web Application Firewall DRS rule groups and rules](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules)
- [Bot protection overview](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-configure-bot-protection)
- [Web Application Firewall best practices](https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices)
- [Configure WAF policies for Application Gateway](https://learn.microsoft.com/azure/web-application-firewall/ag/create-waf-policy-ag)
- [Monitor Application Gateway WAF](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-metrics)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.network/applicationgatewaywebapplicationfirewallpolicies)
10 changes: 5 additions & 5 deletions docs/examples/resources/appgw.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ resource appgw 'Microsoft.Network/applicationGateways@2024-07-01' = {
}

// An example of an Web Application Firewall policy configure with OWASP and Microsoft_BotManagerRuleSet rule sets.
resource waf 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-01-01' = {
name: 'agwwaf'
resource waf 'Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies@2024-10-01' = {
name: name
location: location
properties: {
managedRules: {
managedRuleSets: [
{
ruleSetType: 'OWASP'
ruleSetVersion: '3.2'
ruleSetType: 'Microsoft_DefaultRuleSet'
ruleSetVersion: '2.1'
}
{
ruleSetType: 'Microsoft_BotManagerRuleSet'
ruleSetVersion: '0.1'
ruleSetVersion: '1.1'
}
]
}
Expand Down
12 changes: 6 additions & 6 deletions docs/examples/resources/appgw.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.36.1.42791",
"templateHash": "17115327554579347923"
"version": "0.38.33.27573",
"templateHash": "4094220895201731400"
}
},
"parameters": {
Expand Down Expand Up @@ -63,19 +63,19 @@
},
{
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies",
"apiVersion": "2024-01-01",
"apiVersion": "2024-10-01",
"name": "agwwaf",
"location": "[parameters('location')]",
"properties": {
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.2"
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.1"
},
{
"ruleSetType": "Microsoft_BotManagerRuleSet",
"ruleSetVersion": "0.1"
"ruleSetVersion": "1.1"
}
]
},
Expand Down
31 changes: 19 additions & 12 deletions src/PSRule.Rules.Azure/rules/Azure.AppGwWAF.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,31 +72,38 @@ spec:

---

# Synopsis: Application Gateways WAF should have at least 2 Rule Groups. One for OWASP and one for Microsoft_BotManagerRuleSet.
# Synopsis: Application Gateways WAF should have at least 2 Rule Groups. One for Microsoft_DefaultRuleSet and one for Microsoft_BotManagerRuleSet.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Azure.AppGwWAF.RuleGroups
ref: AZR-000304
tags:
release: GA
ruleSet: 2024_03
ruleSet: 2025_12
Azure.WAF/pillar: Security
labels:
Azure.WAF/maturity: L2
spec:
type:
- Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
condition:
allOf:
# WAF policy has at least two rule groups. OWASP 3.2 is the minimum. Microsoft_BotManagerRuleSet 1.0 is the minimum.
- field: Properties.managedRules.managedRuleSets
# WAF policy has at least two rule groups. Microsoft_DefaultRuleSet 2.1 is the minimum. Microsoft_BotManagerRuleSet 1.0 is the minimum.
- field: properties.managedRules.managedRuleSets
greaterOrEquals: 2
- field: Properties.managedRules.managedRuleSets[0].ruleSetType
equals: OWASP
- field: Properties.managedRules.managedRuleSets[0].ruleSetVersion
version: '>=3.2'
- field: Properties.managedRules.managedRuleSets[1].ruleSetType
equals: Microsoft_BotManagerRuleSet
- field: Properties.managedRules.managedRuleSets[1].ruleSetVersion
version: '>=1.0'
- field: properties.managedRules.managedRuleSets
anyOf:
- allOf:
- field: ruleSetType
equals: Microsoft_DefaultRuleSet
- field: ruleSetVersion
version: '>=2.1'
- allOf:
- field: ruleSetType
equals: Microsoft_BotManagerRuleSet
- field: ruleSetVersion
version: '>=1.0'
count: 2

#endregion Rules
14 changes: 7 additions & 7 deletions tests/PSRule.Rules.Azure.Tests/Azure.Baseline.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_03' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 391;
$filteredResult.Length | Should -Be 390;
}

It 'With Azure.Preview_2024_03' {
Expand All @@ -248,7 +248,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_06' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 411;
$filteredResult.Length | Should -Be 410;
}

It 'With Azure.Preview_2024_06' {
Expand All @@ -262,7 +262,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_09' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 428;
$filteredResult.Length | Should -Be 427;
}

It 'With Azure.Preview_2024_09' {
Expand All @@ -276,7 +276,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_12' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 431;
$filteredResult.Length | Should -Be 430;
}

It 'With Azure.Preview_2024_12' {
Expand All @@ -290,7 +290,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2025_03' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 438;
$filteredResult.Length | Should -Be 437;
}

It 'With Azure.Preview_2025_03' {
Expand All @@ -304,7 +304,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2025_06' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 476;
$filteredResult.Length | Should -Be 475;
}

It 'With Azure.Preview_2025_06' {
Expand All @@ -318,7 +318,7 @@ Describe 'Baselines' -Tag Baseline {
$result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2025_09' -WarningAction Ignore);
$filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'});
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.Length | Should -Be 481;
$filteredResult.Length | Should -Be 480;
}

It 'With Azure.Preview_2025_09' {
Expand Down
14 changes: 7 additions & 7 deletions tests/PSRule.Rules.Azure.Tests/Resources.AppGwWAF.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.2",
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.1",
"ruleGroupOverrides": []
},
{
Expand Down Expand Up @@ -54,8 +54,8 @@
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.1",
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.0",
"ruleGroupOverrides": []
},
{
Expand Down Expand Up @@ -90,13 +90,13 @@
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.2",
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.1",
"ruleGroupOverrides": []
},
{
"ruleSetType": "Microsoft_BotManagerRuleSet",
"ruleSetVersion": "1.0",
"ruleSetVersion": "1.1",
"ruleGroupOverrides": []
}
],
Expand Down
Loading