Skip to content

Commit 2af9f1f

Browse files
akshaym6Akshay Muraliamazumder-msftBethanyZhou
authored
Added new parameters to AzApplicationGatewayFirewallPolicySettings for CustomBlockResponseFeature (#19971)
* Powershell changes for waf custom block response feature * Added test record * Update ChangeLog.md * Updating sdk version for 2022-07-01 * Updated tests * Update ChangeLog.md Co-authored-by: Akshay Murali <[email protected]> Co-authored-by: Adishree Mazumder <[email protected]> Co-authored-by: Beisi Zhou <[email protected]>
1 parent 03029e4 commit 2af9f1f

11 files changed

+2280
-4
lines changed

src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,13 @@ public void TestApplicationGatewayFirewallPolicyWithUppercaseTransform()
237237
{
238238
TestRunner.RunTestScript("Test-ApplicationGatewayFirewallPolicyWithUppercaseTransform");
239239
}
240+
241+
[Fact]
242+
[Trait(Category.AcceptanceType, Category.CheckIn)]
243+
[Trait(Category.Owner, NrpTeamAlias.nvadev_subset1)]
244+
public void TestApplicationGatewayFirewallPolicyWithCustomBlockResponse()
245+
{
246+
TestRunner.RunTestScript("Test-ApplicationGatewayFirewallPolicyWithCustomBlockResponse");
247+
}
240248
}
241249
}

src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.ps1

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4270,3 +4270,91 @@ function Test-ApplicationGatewayFirewallPolicyWithUppercaseTransform
42704270
Clean-ResourceGroup $rgname
42714271
}
42724272
}
4273+
4274+
function Test-ApplicationGatewayFirewallPolicyWithCustomBlockResponse
4275+
{
4276+
# Setup
4277+
$location = Get-ProviderLocation "Microsoft.Network/applicationGateways" "West US 2"
4278+
4279+
$rgname = Get-ResourceGroupName
4280+
$wafPolicy = Get-ResourceName
4281+
4282+
try
4283+
{
4284+
$resourceGroup = New-AzResourceGroup -Name $rgname -Location $location -Tags @{ testtag = "APPGw tag"}
4285+
4286+
# Test both status and body are present
4287+
$customBlockResponseBody = "Sorry! Forbidden"
4288+
$policySettings = New-AzApplicationGatewayFirewallPolicySetting -Mode Prevention -State Enabled -MaxFileUploadInMb 70 -MaxRequestBodySizeInKb 70 -CustomBlockResponseStatusCode 405 -CustomBlockResponseBody $customBlockResponseBody
4289+
$managedRuleSet = New-AzApplicationGatewayFirewallPolicyManagedRuleSet -RuleSetType "OWASP" -RuleSetVersion "3.2"
4290+
$managedRule = New-AzApplicationGatewayFirewallPolicyManagedRule -ManagedRuleSet $managedRuleSet
4291+
New-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname -Location $location -ManagedRule $managedRule -PolicySetting $policySettings
4292+
4293+
$policy = Get-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname
4294+
4295+
Assert-AreEqual $policySettings.FileUploadLimitInMb $policy.PolicySettings.FileUploadLimitInMb
4296+
Assert-AreEqual $policySettings.MaxRequestBodySizeInKb $policy.PolicySettings.MaxRequestBodySizeInKb
4297+
Assert-AreEqual $policySettings.RequestBodyCheck $policy.PolicySettings.RequestBodyCheck
4298+
Assert-AreEqual $policySettings.Mode $policy.PolicySettings.Mode
4299+
Assert-AreEqual $policySettings.State $policy.PolicySettings.State
4300+
Assert-AreEqual $policySettings.CustomBlockResponseStatusCode $policy.CustomBlockResponseStatusCode
4301+
Assert-AreEqual $customBlockResponseBody $policy.CustomBlockResponseBody
4302+
4303+
# test status code alone present
4304+
$policySettings = New-AzApplicationGatewayFirewallPolicySetting -Mode Prevention -State Enabled -MaxFileUploadInMb 70 -MaxRequestBodySizeInKb 70 -CustomBlockResponseStatusCode 405
4305+
$managedRuleSet = New-AzApplicationGatewayFirewallPolicyManagedRuleSet -RuleSetType "OWASP" -RuleSetVersion "3.2"
4306+
$managedRule = New-AzApplicationGatewayFirewallPolicyManagedRule -ManagedRuleSet $managedRuleSet
4307+
Set-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname -ManagedRule $managedRule -PolicySetting $policySettings
4308+
4309+
$policy = Get-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname
4310+
4311+
# Check firewall policy
4312+
Assert-AreEqual $policySettings.FileUploadLimitInMb $policy.PolicySettings.FileUploadLimitInMb
4313+
Assert-AreEqual $policySettings.MaxRequestBodySizeInKb $policy.PolicySettings.MaxRequestBodySizeInKb
4314+
Assert-AreEqual $policySettings.RequestBodyCheck $policy.PolicySettings.RequestBodyCheck
4315+
Assert-AreEqual $policySettings.Mode $policy.PolicySettings.Mode
4316+
Assert-AreEqual $policySettings.State $policy.PolicySettings.State
4317+
Assert-AreEqual $policySettings.CustomBlockResponseStatusCode $policy.CustomBlockResponseStatusCode
4318+
Assert-Null $policy.CustomBlockResponseBody
4319+
4320+
# test body alone present
4321+
$customBlockResponseBody = "Sorry! Forbidden. You can't access"
4322+
$policySettings = New-AzApplicationGatewayFirewallPolicySetting -Mode Prevention -State Enabled -MaxFileUploadInMb 70 -MaxRequestBodySizeInKb 70 -CustomBlockResponseBody $customBlockResponseBody
4323+
$managedRuleSet = New-AzApplicationGatewayFirewallPolicyManagedRuleSet -RuleSetType "OWASP" -RuleSetVersion "3.2"
4324+
$managedRule = New-AzApplicationGatewayFirewallPolicyManagedRule -ManagedRuleSet $managedRuleSet
4325+
Set-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname -ManagedRule $managedRule -PolicySetting $policySettings
4326+
4327+
$policy = Get-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname
4328+
4329+
# Check firewall policy
4330+
Assert-AreEqual $policySettings.FileUploadLimitInMb $policy.PolicySettings.FileUploadLimitInMb
4331+
Assert-AreEqual $policySettings.MaxRequestBodySizeInKb $policy.PolicySettings.MaxRequestBodySizeInKb
4332+
Assert-AreEqual $policySettings.RequestBodyCheck $policy.PolicySettings.RequestBodyCheck
4333+
Assert-AreEqual $policySettings.Mode $policy.PolicySettings.Mode
4334+
Assert-AreEqual $policySettings.State $policy.PolicySettings.State
4335+
Assert-Null $policy.CustomBlockResponseStatusCode
4336+
Assert-AreEqual $customBlockResponseBody $policy.CustomBlockResponseBody
4337+
4338+
# test both are not present
4339+
$policySettings = New-AzApplicationGatewayFirewallPolicySetting -Mode Prevention -State Enabled -MaxFileUploadInMb 70 -MaxRequestBodySizeInKb 70
4340+
$managedRuleSet = New-AzApplicationGatewayFirewallPolicyManagedRuleSet -RuleSetType "OWASP" -RuleSetVersion "3.2"
4341+
$managedRule = New-AzApplicationGatewayFirewallPolicyManagedRule -ManagedRuleSet $managedRuleSet
4342+
Set-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname -ManagedRule $managedRule -PolicySetting $policySettings
4343+
4344+
$policy = Get-AzApplicationGatewayFirewallPolicy -Name $wafPolicy -ResourceGroupName $rgname
4345+
4346+
# Check firewall policy
4347+
Assert-AreEqual $policySettings.FileUploadLimitInMb $policy.PolicySettings.FileUploadLimitInMb
4348+
Assert-AreEqual $policySettings.MaxRequestBodySizeInKb $policy.PolicySettings.MaxRequestBodySizeInKb
4349+
Assert-AreEqual $policySettings.RequestBodyCheck $policy.PolicySettings.RequestBodyCheck
4350+
Assert-AreEqual $policySettings.Mode $policy.PolicySettings.Mode
4351+
Assert-AreEqual $policySettings.State $policy.PolicySettings.State
4352+
Assert-Null $policy.CustomBlockResponseStatusCode
4353+
Assert-Null $policy.CustomBlockResponseBody
4354+
}
4355+
finally
4356+
{
4357+
# Cleanup
4358+
Clean-ResourceGroup $rgname
4359+
}
4360+
}

src/Network/Network.Test/SessionRecords/Commands.Network.Test.ScenarioTests.ApplicationGatewayTests/TestApplicationGatewayFirewallPolicyWithCustomBlockResponse.json

Lines changed: 2059 additions & 0 deletions
Large diffs are not rendered by default.

src/Network/Network/ChangeLog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
--->
2020

2121
## Upcoming Release
22-
* Upgraded AutoMapper to Microsoft.Azure.PowerShell.AutoMapper 6.2.2 with fix [#18721]
22+
* Added optional parameters `CustomBlockResponseStatusCode` and `CustomBlockResponseBody` parameter to `AzApplicationGatewayFirewallPolicySettings`
2323

2424
## Version 5.1.2
2525
* Upgraded AutoMapper to Microsoft.Azure.PowerShell.AutoMapper 6.2.2 with fix [#18721]

src/Network/Network/FirewallPolicy/GetAzureApplicationGatewayFirewallPolicyCommand.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
using Microsoft.Azure.Management.Network.Models;
2020
using Microsoft.Rest.Azure;
2121
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
22+
using System;
23+
using System.Text;
2224

2325
namespace Microsoft.Azure.Commands.Network
2426
{
@@ -42,13 +44,29 @@ public class GetAzureApplicationGatewayFirewallPolicyCommand : ApplicationGatewa
4244
[ValidateNotNullOrEmpty]
4345
public virtual string ResourceGroupName { get; set; }
4446

47+
// CustomBlockResponse body is stored as base64. We need to convert it back to string during a GET call
48+
private void ConvertCustomBlockResponseBodyToString(PSApplicationGatewayWebApplicationFirewallPolicy firewallPolicy)
49+
{
50+
byte[] customBlockResponseBodyByteArray = Convert.FromBase64String(firewallPolicy.PolicySettings.CustomBlockResponseBody);
51+
firewallPolicy.PolicySettings.CustomBlockResponseBody = Encoding.UTF8.GetString(customBlockResponseBodyByteArray);
52+
}
53+
4554
public override void ExecuteCmdlet()
4655
{
4756
base.ExecuteCmdlet();
4857
if (!string.IsNullOrEmpty(this.Name))
4958
{
5059
var firewallPolicy = this.GetApplicationGatewayFirewallPolicy(this.ResourceGroupName, this.Name);
5160

61+
if (!string.IsNullOrEmpty(firewallPolicy.PolicySettings.CustomBlockResponseBody))
62+
{
63+
ConvertCustomBlockResponseBodyToString(firewallPolicy);
64+
}
65+
66+
// Assign the CustomBlockResponse fields from policy settings to policy (Feature parity with AFD WAF Policy)
67+
firewallPolicy.CustomBlockResponseStatusCode = firewallPolicy.PolicySettings.CustomBlockResponseStatusCode;
68+
firewallPolicy.CustomBlockResponseBody = firewallPolicy.PolicySettings.CustomBlockResponseBody;
69+
5270
WriteObject(firewallPolicy);
5371
}
5472
else
@@ -72,6 +90,15 @@ public override void ExecuteCmdlet()
7290
{
7391
var psFirewallPolicy = this.ToPsApplicationGatewayFirewallPolicy(firewallPolicy);
7492
psFirewallPolicy.ResourceGroupName = NetworkBaseCmdlet.GetResourceGroup(firewallPolicy.Id);
93+
94+
if (!string.IsNullOrEmpty(psFirewallPolicy.PolicySettings.CustomBlockResponseBody))
95+
{
96+
ConvertCustomBlockResponseBodyToString(psFirewallPolicy);
97+
}
98+
99+
psFirewallPolicy.CustomBlockResponseStatusCode = psFirewallPolicy.PolicySettings.CustomBlockResponseStatusCode;
100+
psFirewallPolicy.CustomBlockResponseBody = psFirewallPolicy.PolicySettings.CustomBlockResponseBody;
101+
75102
psFirewallPolicies.Add(psFirewallPolicy);
76103
}
77104

src/Network/Network/FirewallPolicy/NewAzureApplicationGatewayFirewallPolicyCommand.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
using Microsoft.Azure.Commands.ResourceManager.Common.Tags;
1919
using Microsoft.Azure.Management.Network;
2020
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
21+
using System;
2122
using System.Collections;
2223
using System.Collections.Generic;
2324
using System.Linq;
2425
using System.Management.Automation;
26+
using System.Text;
2527
using MNM = Microsoft.Azure.Management.Network.Models;
2628

2729
namespace Microsoft.Azure.Commands.Network
@@ -147,6 +149,17 @@ private PSApplicationGatewayWebApplicationFirewallPolicy CreateApplicationGatewa
147149
// Execute the Create ApplicationGatewayFirewallPolicy call
148150
this.ApplicationGatewayFirewallPolicyClient.CreateOrUpdate(this.ResourceGroupName, this.Name, firewallPolicyModel);
149151
var getApplicationGatewayFirewallPolicy = this.GetApplicationGatewayFirewallPolicy(this.ResourceGroupName, this.Name);
152+
153+
// Assign the CustomBlockResponse fields from policy settings to policy (Feature parity with AFD WAF Policy)
154+
getApplicationGatewayFirewallPolicy.CustomBlockResponseStatusCode = getApplicationGatewayFirewallPolicy.PolicySettings.CustomBlockResponseStatusCode;
155+
156+
if (!string.IsNullOrEmpty(getApplicationGatewayFirewallPolicy.PolicySettings.CustomBlockResponseBody))
157+
{
158+
// decode the body value as it is base64 encoded
159+
string decodedCustomBlockResponseBody = Encoding.UTF8.GetString(Convert.FromBase64String(getApplicationGatewayFirewallPolicy.PolicySettings.CustomBlockResponseBody));
160+
getApplicationGatewayFirewallPolicy.CustomBlockResponseBody = decodedCustomBlockResponseBody;
161+
}
162+
150163
return getApplicationGatewayFirewallPolicy;
151164
}
152165
}

src/Network/Network/FirewallPolicy/PolicySettings/AzureApplicationGatewayFirewallPolicySetting.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
// ----------------------------------------------------------------------------------
1414

1515
using Microsoft.Azure.Commands.Network.Models;
16+
using Microsoft.WindowsAzure.Commands.Utilities.Common;
1617
using System.Collections.Generic;
1718
using System.Management.Automation;
19+
using System.Text;
1820

1921
namespace Microsoft.Azure.Commands.Network
2022
{
@@ -46,6 +48,14 @@ public class AzureApplicationGatewayFirewallPolicySetting : NetworkBaseCmdlet
4648
[ValidateNotNullOrEmpty]
4749
public int MaxFileUploadInMb { get; set; }
4850

51+
[Parameter(Mandatory = false, HelpMessage = "Custom Response Status Code")]
52+
[ValidateNotNullOrEmpty]
53+
public int? CustomBlockResponseStatusCode { get; set; }
54+
55+
[Parameter(Mandatory = false, HelpMessage = "Custom Response Body")]
56+
[ValidateNotNullOrEmpty]
57+
public string CustomBlockResponseBody { get; set; }
58+
4959
public override void ExecuteCmdlet()
5060
{
5161
base.ExecuteCmdlet();
@@ -69,6 +79,21 @@ public override void ExecuteCmdlet()
6979
{
7080
this.MaxFileUploadInMb = 100;
7181
}
82+
83+
if (!this.MyInvocation.BoundParameters.ContainsKey("CustomBlockResponseStatusCode"))
84+
{
85+
this.CustomBlockResponseStatusCode = (int?)null;
86+
}
87+
88+
if (this.MyInvocation.BoundParameters.ContainsKey("CustomBlockResponseBody"))
89+
{
90+
this.CustomBlockResponseBody = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(CustomBlockResponseBody));
91+
} else
92+
{
93+
this.CustomBlockResponseBody = null;
94+
}
95+
96+
7297
}
7398

7499
protected PSApplicationGatewayFirewallPolicySettings NewObject()
@@ -79,7 +104,9 @@ protected PSApplicationGatewayFirewallPolicySettings NewObject()
79104
State = this.State,
80105
RequestBodyCheck = this.DisableRequestBodyCheck.IsPresent ? false : true,
81106
MaxRequestBodySizeInKb = this.MaxRequestBodySizeInKb,
82-
FileUploadLimitInMb = this.MaxFileUploadInMb
107+
FileUploadLimitInMb = this.MaxFileUploadInMb,
108+
CustomBlockResponseBody = this.CustomBlockResponseBody,
109+
CustomBlockResponseStatusCode = this.CustomBlockResponseStatusCode,
83110
};
84111
}
85112
}

src/Network/Network/FirewallPolicy/SetAzureApplicationGatewayFirewallPolicyCommand.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using System.Linq;
2323
using System.Management.Automation;
2424
using MNM = Microsoft.Azure.Management.Network.Models;
25+
using System.Text;
2526

2627
namespace Microsoft.Azure.Commands.Network
2728
{
@@ -134,6 +135,17 @@ public override void ExecuteCmdlet()
134135
this.ApplicationGatewayFirewallPolicyClient.CreateOrUpdate(ResourceGroupName, Name, firewallPolicyModel);
135136

136137
var getApplicationGatewayFirewallPolicy = this.GetApplicationGatewayFirewallPolicy(ResourceGroupName, Name);
138+
139+
// Assign the CustomBlockResponse fields from policy settings to policy (Feature parity with AFD WAF Policy)
140+
getApplicationGatewayFirewallPolicy.CustomBlockResponseStatusCode = getApplicationGatewayFirewallPolicy.PolicySettings.CustomBlockResponseStatusCode;
141+
142+
// decode the body value as it is base64 encoded
143+
if (!string.IsNullOrEmpty(getApplicationGatewayFirewallPolicy.PolicySettings.CustomBlockResponseBody))
144+
{
145+
string decodedCustomBlockResponseBody = Encoding.UTF8.GetString(Convert.FromBase64String(getApplicationGatewayFirewallPolicy.PolicySettings.CustomBlockResponseBody));
146+
getApplicationGatewayFirewallPolicy.CustomBlockResponseBody = decodedCustomBlockResponseBody;
147+
}
148+
137149
WriteObject(getApplicationGatewayFirewallPolicy);
138150
}
139151
}

src/Network/Network/Models/PSApplicationGatewayFirewallPolicySettings.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,11 @@ public partial class PSApplicationGatewayFirewallPolicySettings
3636

3737
[Ps1Xml(Target = ViewControl.Table)]
3838
public int FileUploadLimitInMb { get; set; }
39+
40+
[Ps1Xml(Target = ViewControl.Table)]
41+
public string CustomBlockResponseBody { get; set; }
42+
43+
[Ps1Xml(Target = ViewControl.Table)]
44+
public int? CustomBlockResponseStatusCode { get; set; }
3945
}
4046
}

src/Network/Network/Models/PSApplicationGatewayWebApplicationFirewallPolicy.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,11 @@ public class PSApplicationGatewayWebApplicationFirewallPolicy : PSTopLevelResour
2626
public PSApplicationGatewayFirewallPolicySettings PolicySettings { get; set; }
2727

2828
public PSApplicationGatewayFirewallPolicyManagedRules ManagedRules { get; set; }
29+
30+
// CustomBlockResponse fields to be mapped from inside the policy settings
31+
// to be shown as response in PS (Feature parity with AFD WAF Policy)
32+
public int? CustomBlockResponseStatusCode { get; set; }
33+
34+
public string CustomBlockResponseBody { get; set; }
2935
}
3036
}

src/Network/Network/help/New-AzApplicationGatewayFirewallPolicySetting.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ Creates a policy setting for the firewall policy
1414

1515
```
1616
New-AzApplicationGatewayFirewallPolicySetting [-Mode <String>] [-State <String>] [-DisableRequestBodyCheck]
17-
[-MaxRequestBodySizeInKb <Int32>] [-MaxFileUploadInMb <Int32>] [-DefaultProfile <IAzureContextContainer>]
18-
[<CommonParameters>]
17+
[-MaxRequestBodySizeInKb <Int32>] [-MaxFileUploadInMb <Int32>] [-CustomBlockResponseStatusCode <Int32>]
18+
[-CustomBlockResponseBody <String>] [-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
1919
```
2020

2121
## DESCRIPTION
@@ -33,6 +33,36 @@ The new policySettings is stored to $condition.
3333

3434
## PARAMETERS
3535

36+
### -CustomBlockResponseBody
37+
Custom Block Response Body in policy settings of the firewall policy.
38+
39+
```yaml
40+
Type: System.String
41+
Parameter Sets: (All)
42+
Aliases:
43+
44+
Required: False
45+
Position: Named
46+
Default value: None
47+
Accept pipeline input: False
48+
Accept wildcard characters: False
49+
```
50+
51+
### -CustomBlockResponseStatusCode
52+
Custom block response status code in policy settings of the firewall policy.
53+
54+
```yaml
55+
Type: System.Nullable`1[System.Int32]
56+
Parameter Sets: (All)
57+
Aliases:
58+
59+
Required: False
60+
Position: Named
61+
Default value: None
62+
Accept pipeline input: False
63+
Accept wildcard characters: False
64+
```
65+
3666
### -DefaultProfile
3767
The credentials, account, tenant, and subscription used for communication with Azure.
3868

0 commit comments

Comments
 (0)