AzureWAF
The Azure WAF (Web Application Firewall) integration provides centralized protection of your web applications from common exploits and vulnerabilities. It enables you to control policies that are configured in the Azure Firewall management platform, and allows you to add, delete, or update policies, and also to get details of a specific policy or a list of policies.
Network Security · Azure WAF
Details
| ID | AzureWAF |
|---|---|
| Provider | Microsoft |
| Category | Network Security |
| From Version | 5.0.0 |
| Docker Image | demisto/crypto:1.0.0.8931184 |
| Supported Modules | Agentix XSIAM |
README
The Azure WAF (Web Application Firewall) integration provides centralized protection of your web applications from common exploits and vulnerabilities.
It enables you to control policies that are configured in the Azure Firewall management platform, and allows you to add, delete, or update policies,
and also to get details of a specific policy or a list of policies.
In order to connect to the AzureWAF using either Cortex XSOAR Azure App or the Self-Deployed Azure App, use one of the following methods:
- Authorization Code Flow (Recommended).
- Device Code Flow.
- Azure Managed Identities
- Client Credentials Flow.
Self-Deployed Application
To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal.
Required Permissions
The following API permissions are required in Azure:
| API | Permission |
|---|---|
| Azure Service Management | user_impersonation |
| Microsoft Graph | offline_access |
| Microsoft Graph | User.Read |
Authentication Using the Authorization Code Flow (recommended)
Follow these steps for a self-deployed configuration:
- To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal. To add the registration, refer to the following Microsoft article steps 1-8.
- choose the Authorization Code option in the Authentication Type parameter.
- Enter your Client/Application ID in the Application ID parameter.
- Enter your Client Secret in the Client Secret parameter.
- Enter your Tenant ID in the Tenant ID parameter.
- Enter your Application redirect URI in the Application redirect URI parameter.
- Save the instance.
- Run the !azure-waf-generate-login-url command in the War Room and follow the instruction.
- Run the !azure-waf-auth-test command - a ‘Success’ message should be printed to the War Room.
Authentication Using the Device Code Flow
Use the device code flow
to link Azure SQL Management with Cortex XSOAR.
In order to connect to Azure Web Application Firewall using either the Cortex XSOAR Azure or Self Deployed Azure application:
- Fill in the required parameters
- choose the Device Code option in the Authentication Type parameter.
- Run the !azure-waf-auth-start command.
- Follow the instructions that appear.
- Run the !azure-waf-auth-complete command.
At end of the process, you will see a message that you logged in successfully.
Cortex XSOAR Azure app
In order to use the Cortex XSOAR Azure application, use the default application ID (cf22fd73-29f1-4245-8e16-533704926d20) and fill in your subscription ID and default resource group name.
You only need to fill in your subscription ID and resource group name. You can find your resource group and
subscription ID in the Azure Portal. For a more detailed explanation, visit this page.
Azure Managed Identities Authentication
Note: This option is relevant only if the integration is running on Azure VM
Follow one of these steps for authentication based on Azure Managed Identities:
-
To use System Assigned Managed Identity
- In the Authentication Type drop-down list, select Azure Managed Identities and leave the Azure Managed Identities Client ID field empty.
-
To use User Assigned Managed Identity
- Go to Azure Portal -> Managed Identities.
- Select your User Assigned Managed Identity -> copy the Client ID -> paste it in the Azure Managed Identities client id field in the instance configuration.
- In the Authentication Type drop-down list, select Azure Managed Identities.
For more information, see Managed identities for Azure resources.
Client Credentials Flow Authentication
Assign Azure roles using the Azure portal Microsoft article
Note: In the Select members section, assign the application you created earlier.
To configure a Microsoft integration that uses this authorization flow with a self-deployed Azure application:
- In the Authentication Type field, select the Client Credentials option.
- In the Application ID field, enter your Client/Application ID.
- In the Tenant ID field, enter your Tenant ID .
- In the Client Secret field, enter your Client Secret.
- Click Test to validate the URLs, token, and connection
- Save the instance.
Testing authentication and connectivity
If you are using Device Code Flow or Authorization Code Flow, for testing your authentication and connectivity to the AzureWAF service run the !azure-waf-auth-test command.
Configure AzureWAF on Cortex XSOAR/XSIAM
- Navigate to one of the following:
- Cortex XSOAR 8: Settings & Info > Settings > Integrations > Instances
- Cortex XSOAR 6: Settings > Integrations > Servers & Services.
- Cortex XSIAM: Settings > Configurations > Automation & Feed Integrations
- Search for Azure Web Application Firewall.
-
Click Add instance to create and configure a new integration instance.
Parameter Description Required App ID False Default Subscription ID True Default Resource Group Name True Authentication Type Type of authentication - can be Authorization Code Flow (recommended), Device Code Flow, or Azure Managed Identities. True Tenant ID (for authorization code mode) False Client Secret (for authorization code mode) False Client Secret (for authorization code mode) False Application redirect URI (for authorization code mode) False Authorization code for user-auth mode - received from the authorization step. see Detailed Instructions (?) section False Authorization code False Azure Managed Identities Client ID The Managed Identities client ID for authentication - relevant only if the integration is running on Azure VM. False Azure AD endpoint Azure AD endpoint associated with a national cloud. False Trust any certificate (not secure) False Use system proxy settings False - Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
azure-waf-policies-get
Retrieves protection policies within a resource group.
Base Command
azure-waf-policies-get
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of a policy. Used to retrieve a protection policy with a specified name within a resource group. If policy_name is not provided, will retrieve all policies. | Optional |
| resource_group_name | Comma-separated value list of the names of the resource groups. If not provided, the instance’s default resource group name will be used. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
| verbose | Whether to retrieve full details of the policy. Possible values are: “true” and “false”. Default is “false”. | Optional |
| limit | Maximum number of policies to fetch. Default is “10”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.Policy.name | String | Resource name. |
| AzureWAF.Policy.id | String | Resource ID. |
| AzureWAF.Policy.type | String | Resource type. |
| AzureWAF.Policy.etag | String | A unique read-only string that changes whenever the resource is updated. |
| AzureWAF.Policy.tags | String | Resource tag. |
| AzureWAF.Policy.location | String | Resource location. |
| AzureWAF.Policy.properties.resourceState | String | Resource status of the policy. |
| AzureWAF.Policy.properties.provisioningState | String | The provisioning state of the application gateway resource. |
| AzureWAF.Policy.properties.policySettings.state | String | The state of the policy. |
| AzureWAF.Policy.properties.policySettings.mode | String | The mode of the policy. |
| AzureWAF.Policy.properties.policySettings.maxRequestBodySizeInKb | Number | Maximum request body size in Kb for WAF. |
| AzureWAF.Policy.properties.policySettings.fileUploadLimitInMb | Number | Maximum file upload size in Mb for WAF. |
| AzureWAF.Policy.properties.policySettings.requestBodyCheck | Boolean | Whether to allow WAF to check the request body. |
| AzureWAF.Policy.properties.customRules.name | String | The name of the resource that is unique within a policy. This name can be used to access the resource. |
| AzureWAF.Policy.properties.customRules.priority | Number | Priority of the rule. Rules with a lower value will be evaluated before rules with a higher value. |
| AzureWAF.Policy.properties.customRules.ruleType | String | The rule type. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchVariables.variableName | String | Match variable. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchVariables.selector | String | The selector of the match variable. |
| AzureWAF.Policy.properties.customRules.matchConditions.operator | String | The operator to be matched. |
| AzureWAF.Policy.properties.customRules.matchConditions.negationCondition | Boolean | Whether this is a negate condition. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchValues | String | Match value. |
| AzureWAF.Policy.properties.customRules.action | String | Type of actions. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleSetType | String | The rule set type to use. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleSetVersion | String | The version of the rule set to use. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.ruleGroupName | String | The managed rule group to override. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.rules.ruleId | String | Identifier for the managed rule. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.rules.state | String | The state of the managed rule. Defaults to disabled if not specified. |
| AzureWAF.Policy.properties.managedRules.exclusions.matchVariable | String | The variable to be excluded. |
| AzureWAF.Policy.properties.managedRules.exclusions.selectorMatchOperator | String | When matchVariable is a collection, operate on the selector to specify which elements in the collection this exclusion applies to. |
| AzureWAF.Policy.properties.managedRules.exclusions.selector | String | When matchVariable is a collection, the operator used to specify which elements in the collection this exclusion applies to. |
Command Example
!azure-waf-policies-get limit=2
Context Example
{
"AzureWAF": {
"Policy": [
{
"etag": "W/\"4bf9c37a-81b7-4c14-a27c-67962c7af825\"",
"id": "/subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example_policy",
"location": "example_location",
"name": "example_policy",
"properties": {
"customRules": [],
"managedRules": {
"exclusions": [],
"managedRuleSets": [
{
"ruleGroupOverrides": [],
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
}
]
},
"policySettings": {
"fileUploadLimitInMb": 750,
"maxRequestBodySizeInKb": 128,
"mode": "Detection",
"requestBodyCheck": true,
"state": "Disabled"
},
"provisioningState": "Succeeded"
},
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies"
}
]
}
}
Human Readable Output
Policy: example_policy
etag id location name type W/”4bf9c37a” /subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example_policy westus example_policy Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies Policy: test_policy
|etag|id|location|name|type|
|—|—|—|—|—|
| W/”4e844e6c” | /subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/test_policy | westus | test_policy | Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies |
Showing 2 policies out of 7
azure-waf-policies-list-all-in-subscription
Retrieves all the WAF policies in a subscription.
Base Command
azure-waf-policies-list-all-in-subscription
Input
| Argument Name | Description | Required |
|---|---|---|
| verbose | Whether to retrieve the full details of the policy. Possible values are “true” and “false”. Default is “false”. | Optional |
| limit | Maximum number of policies to be shown. (This will only affect visualized data, not context.). Default is 10. | Optional |
| subscription_id | Comma-separated list of subscription IDs. Will override the default subscription ID. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.Policy.name | String | Resource name. |
| AzureWAF.Policy.id | String | Resource ID. |
| AzureWAF.Policy.type | String | Resource type. |
| AzureWAF.Policy.etag | String | A unique read-only string that changes whenever the resource is updated. |
| AzureWAF.Policy.tags | String | Resource tags. |
| AzureWAF.Policy.location | String | Resource location. |
| AzureWAF.Policy.properties.resourceState | String | Resource status of the policy. |
| AzureWAF.Policy.properties.provisioningState | String | The provisioning state of the application gateway resource. |
| AzureWAF.Policy.properties.policySettings.state | String | The state of the policy. |
| AzureWAF.Policy.properties.policySettings.mode | String | The mode of the policy. |
| AzureWAF.Policy.properties.policySettings.maxRequestBodySizeInKb | Number | Maximum request body size in Kb for WAF. |
| AzureWAF.Policy.properties.policySettings.fileUploadLimitInMb | Number | Maximum file upload size in Mb for WAF. |
| AzureWAF.Policy.properties.policySettings.requestBodyCheck | Boolean | Whether to allow WAF to check the request body. |
| AzureWAF.Policy.properties.customRules.name | String | The name of the resource that is unique within a policy. This name can be used to access the resource. |
| AzureWAF.Policy.properties.customRules.priority | Number | Priority of the rule. Rules with a lower value will be evaluated before rules with a higher value. |
| AzureWAF.Policy.properties.customRules.ruleType | String | The rule type. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchVariables.variableName | String | Match variable. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchVariables.selector | String | The selector of the match variable. |
| AzureWAF.Policy.properties.customRules.matchConditions.operator | String | The operator to be matched. |
| AzureWAF.Policy.properties.customRules.matchConditions.negationConditon | Boolean | Whether this is a negate condition. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchValues | String | Match value. |
| AzureWAF.Policy.properties.customRules.action | String | Type of actions. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleSetType | String | The rule set type to use. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleSetVersion | String | The version of the rule set to use. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.ruleGroupName | String | The managed rule group to override. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.rules.ruleId | String | Identifier for the managed rule. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.rules.state | String | The state of the managed rule. Defaults to disabled if not specified. |
| AzureWAF.Policy.properties.managedRules.exclusions.matchVariable | String | The variable to be excluded. |
| AzureWAF.Policy.properties.managedRules.exclusions.selectorMatchOperator | String | When matchVariable is a collection, operate on the selector to specify which elements in the collection this exclusion applies to. |
| AzureWAF.Policy.properties.managedRules.exclusions.selector | String | When matchVariable is a collection, the operator used to specify which elements in the collection this exclusion applies to. |
Command Example
!azure-waf-policies-list-all-in-subscription limit=2
Context Example
{
"AzureWAF": {
"Policy": [
{
"etag": "W/\"4bf9c37a-81b7-4c14-a27c-67962c7af825\"",
"id": "/subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example_policy",
"location": "westus",
"name": "example_policy",
"properties": {
"customRules": [],
"managedRules": {
"exclusions": [],
"managedRuleSets": [
{
"ruleGroupOverrides": [],
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
}
]
},
"policySettings": {
"fileUploadLimitInMb": 750,
"maxRequestBodySizeInKb": 128,
"mode": "Detection",
"requestBodyCheck": true,
"state": "Disabled"
},
"provisioningState": "Succeeded"
},
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies"
}
]
}
}
Human Readable Output
Policy: example_policy
etag id location name type W/”4bf9c37a” /subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example_policy westus example_policy Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies Policy: test_policy_1608641948_
|etag|id|location|name|type|
|—|—|—|—|—|
| W/”422867fc-a697-4978-83f5-20a57ab51511” | /subscriptions/0f907ea4-bc8b-4c11-9d7e-805c2fd144fb/resourceGroups/demisto-sentinel2/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/test_policy_1608641948_ | westus | test_policy_1608641948_ | Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies |
Showing 2 policies out of 6
azure-waf-policy-update-or-create
Creates or updates a policy with a specified rule set name within a resource group.
Base Command
azure-waf-policy-update-or-create
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of a policy. Used to retrieve a protection policy with a specified name within a resource group. If policy_name is not provided, will retrieve all policies. | Required |
| resource_group_name | Comma-separated list of the names of the resource groups. If not provided, the instance’s default resource group name will be used. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
| managed_rules | Describes the managedRules structure. | Required |
| resource_id | Resource ID. | Optional |
| location | Describes the resource location. | Optional |
| custom_rules | The custom rules inside the policy. | Optional |
| policy_settings | The policy setting for the policy. | Optional |
| verbose | Whether to retrieve the full details of the policy. Possible values are: “true” and “false”. Default is “false”. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.Policy.name | String | Resource name. |
| AzureWAF.Policy.id | String | Resource ID. |
| AzureWAF.Policy.type | String | Resource type. |
| AzureWAF.Policy.etag | String | A unique read-only string that changes whenever the resource is updated. |
| AzureWAF.Policy.tags | String | Resource type. |
| AzureWAF.Policy.location | String | Resource location. |
| AzureWAF.Policy.properties.resourceState | String | Resource status of the policy. |
| AzureWAF.Policy.properties.provisioningState | String | The provisioning state of the application gateway resource. |
| AzureWAF.Policy.properties.policySettings.state | String | The state of the policy. |
| AzureWAF.Policy.properties.policySettings.mode | String | The mode of the policy. |
| AzureWAF.Policy.properties.policySettings.maxRequestBodySizeInKb | Number | Maximum request body size in Kb for WAF. |
| AzureWAF.Policy.properties.policySettings.fileUploadLimitInMb | Number | Maximum file upload size in Mb for WAF. |
| AzureWAF.Policy.properties.policySettings.requestBodyCheck | Boolean | Whether to allow WAF to check the request body. |
| AzureWAF.Policy.properties.customRules.name | String | The name of the resource that is unique within a policy. This name can be used to access the resource. |
| AzureWAF.Policy.properties.customRules.priority | Number | Priority of the rule. Rules with a lower value will be evaluated before rules with a higher value. |
| AzureWAF.Policy.properties.customRules.ruleType | String | The rule type. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchVariables.variableName | String | Match variable. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchVariables.selector | String | The selector of the match variable. |
| AzureWAF.Policy.properties.customRules.matchConditions.operator | String | The operator to be matched. |
| AzureWAF.Policy.properties.customRules.matchConditions.negationConditon | Boolean | Whether this is a negate condition. |
| AzureWAF.Policy.properties.customRules.matchConditions.matchValues | String | Match value. |
| AzureWAF.Policy.properties.customRules.action | String | Type of actions. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleSetType | String | Defines the rule set type to use. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleSetVersion | String | Defines the version of the rule set to use. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.ruleGroupName | String | The managed rule group to override. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.rules.ruleId | String | Identifier for the managed rule. |
| AzureWAF.Policy.properties.managedRules.managedRuleSets.ruleGroupOverrides.rules.state | String | The state of the managed rule. Defaults to disabled if not specified. |
| AzureWAF.Policy.properties.managedRules.exclusions.matchVariable | String | The variable to be excluded. |
| AzureWAF.Policy.properties.managedRules.exclusions.selectorMatchOperator | String | When matchVariable is a collection, operate on the selector to specify which elements in the collection this exclusion applies to. |
| AzureWAF.Policy.properties.managedRules.exclusions.selector | String | When matchVariable is a collection, the operator used to specify which elements in the collection this exclusion applies to. |
Command Example
!azure-waf-policy-update-or-create policy_name="example_policy" resource_group_name="demisto-sentinel2" location="WestUs" managed_rules="{ \"managedRuleSets\": [{\"ruleSetType\": \"OWASP\",\"ruleSetVersion\": \"3.0\"}]}"
Context Example
{
"AzureWAF": {
"Policy": {
"etag": "W/\"f1121c83-d9c1-47a4-912b-6f6731c991a4\"",
"id": "/subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example_policy",
"location": "westus",
"name": "example_policy",
"properties": {
"customRules": [],
"managedRules": {
"exclusions": [],
"managedRuleSets": [
{
"ruleGroupOverrides": [],
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
}
]
},
"policySettings": {
"fileUploadLimitInMb": 100,
"maxRequestBodySizeInKb": 128,
"mode": "Detection",
"requestBodyCheck": true,
"state": "Disabled"
},
"provisioningState": "Updating"
},
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies"
}
}
}
Human Readable Output
Policy: example_policy
|etag|id|location|name|type|
|—|—|—|—|—|
| W/”f1121c83” | /subscriptions/example_subscription/resourceGroups/example_resource_group/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example_policy | westus | example_policy | Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies |
Showing 1 policies out of 1
azure-waf-policy-delete
Deletes a policy.
Base Command
azure-waf-policy-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of a policy. Used to retrieve a protection policy with a specified name within a resource group. If policy_name is not provided, will retrieve all policies. | Required |
| resource_group_name | The name of the resource group. If not provided, the instance’s default resource group name will be used. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
Context Output
There is no context output for this command.
Command Example
!azure-waf-policy-delete policy_name="example_policy"
Human Readable Output
Policy example_policy was deleted successfully.
azure-waf-front-door-policies-list
Lists all of the Front Door protection policies within a resource group.
Base Command
azure-waf-front-door-policies-list
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of a policy. Used to retrieve a protection policy with a specified name within a resource group. If policy_name is not provided, will retrieve all policies. | Optional |
| resource_group_name | Comma-separated value list of the names of the resource groups. If not provided, the instance’s default resource group name will be used. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
| verbose | Whether to retrieve full details of the policy. Possible values are: “true” and “false”. Default is “false”. | Optional |
| limit | Maximum number of policies to fetch. Default is “10”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.FrontDoorPolicy.name | String | Resource name. |
| AzureWAF.FrontDoorPolicy.id | String | Resource ID. |
| AzureWAF.FrontDoorPolicy.type | String | Resource type. |
| AzureWAF.FrontDoorPolicy.etag | String | A unique read-only string that changes whenever the resource is updated. |
| AzureWAF.FrontDoorPolicy.location | String | Resource location. |
Command Example
!azure-waf-front-door-policies-list limit=2
azure-waf-front-door-policies-list-all-in-subscription
Lists all of the Front Door protection policies within a subscription.
Base Command
azure-waf-front-door-policies-list-all-in-subscription
Input
| Argument Name | Description | Required |
|---|---|---|
| verbose | Whether to retrieve the full details of the policy. Possible values are “true” and “false”. Default is “false”. | Optional |
| limit | Maximum number of policies to fetch. Default is “10”. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.FrontDoorPolicy.name | String | Resource name. |
| AzureWAF.FrontDoorPolicy.id | String | Resource ID. |
| AzureWAF.FrontDoorPolicy.type | String | Resource type. |
| AzureWAF.FrontDoorPolicy.etag | String | A unique read-only string that changes whenever the resource is updated. |
| AzureWAF.FrontDoorPolicy.location | String | Resource location. |
Command Example
!azure-waf-front-door-policies-list-all-in-subscription limit=2
azure-waf-front-door-policy-update-or-create
Creates or updates a Front Door policy with a specified rule set name within a resource group.
Base Command
azure-waf-front-door-policy-update-or-create
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of a policy. Used to retrieve a protection policy with a specified name within a resource group. | Required |
| resource_group_name | Comma-separated list of the names of the resource groups. If not provided, the instance’s default resource group name will be used. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
| managed_rules | Describes the managedRules structure. | Required |
| custom_rules | The custom rules inside the policy. | Optional |
| policy_settings | Describes settings for the policy. | Optional |
| location | Describes the resource location. | Optional |
| sku | The pricing tier of web application firewall policy. Defaults to Classic_AzureFrontDoor if not specified. Possible values are: Classic_AzureFrontDoor, Standard_AzureFrontDoor, Premium_AzureFrontDoor. Default is Classic_AzureFrontDoor. | Optional |
| etag | A unique read-only string that changes whenever the resource is updated. | Optional |
| verbose | Whether to retrieve the full details of the policy. Possible values are: “true” and “false”. Default is “false”. | Optional |
| tags | Resource tags. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.FrontDoorPolicy.name | String | Resource name. |
| AzureWAF.FrontDoorPolicy.id | String | Resource ID. |
| AzureWAF.FrontDoorPolicy.type | String | Resource type. |
| AzureWAF.FrontDoorPolicy.etag | String | A unique read-only string that changes whenever the resource is updated. |
| AzureWAF.FrontDoorPolicy.location | String | Resource location. |
Command Example
!azure-waf-front-door-policy-update-or-create policy_name="example_policy" resource_group_name="demisto-sentinel2" location="WestUs" managed_rules="{ \"managedRuleSets\": [{\"ruleSetType\": \"OWASP\",\"ruleSetVersion\": \"3.0\"}]}"
azure-waf-front-door-policy-delete
Deletes a Front Door policy.
Base Command
azure-waf-front-door-policy-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of a policy. Used to retrieve a protection policy with a specified name within a resource group. | Required |
| resource_group_name | Comma-separated list of the name of the resource group. If not provided, the instance’s default resource group name will be used. | Optional |
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
Context Output
There is no context output for this command.
Command Example
!azure-waf-front-door-policy-delete policy_name="example_policy"
Human Readable Output
Front Door Policy example_policy was deleted successfully.
azure-waf-auth-start
Run this command to start the authorization process and follow the instructions provided in the command results.
Base Command
azure-waf-auth-start
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Command Example
!azure-waf-auth-start
Human Readable Output
Authorization instructions
1. To sign in, use a web browser to open the page: [https://microsoft.com/devicelogin](https://microsoft.com/devicelogin) and enter the code **CKVE788YV** to authenticate. 2. Run the **!azure-waf-auth-complete** command in the War Room.
azure-waf-auth-complete
Run this command to complete the authorization process.
Should be used after running the azure_waf-auth-start command.
Base Command
azure-waf-auth-complete
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Command Example
!azure-waf-auth-complete
Human Readable Output
✅ Authorization completed successfully.
azure-waf-auth-reset
Run this command if for some reason you need to rerun the authentication process.
Base Command
azure-waf-auth-reset
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Command Example
!azure-waf-auth-reset
Human Readable Output
Authorization was reset successfully. You can now run !azure-waf-auth-start and !azure-waf-auth-complete.
azure-waf-auth-test
Tests connectivity to the Azure Web Application Firewall.
Base Command
azure-waf-auth-test
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Command Example
!azure-waf-auth-test
Human Readable Output
✅ Great Success!
azure-waf-generate-login-url
Generate the login url used for Authorization code flow.
Base Command
azure-waf-generate-login-url
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Command Example
azure-waf-generate-login-url
Human Readable Output
Authorization instructions
- Click on the login URL to sign in and grant Cortex XSOAR permissions for your Azure Service Management.
You will be automatically redirected to a link with the following structure:
REDIRECT_URI?code=AUTH_CODE&session_state=SESSION_STATE- Copy the
AUTH_CODE(without thecode=prefix, and thesession_stateparameter)
and paste it in your instance configuration under the Authorization code parameter.
azure-waf-subscriptions-list
Gets all subscriptions for a tenant.
Base Command
azure-waf-subscriptions-list
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.Subscription.authorizationSource | String | Subscription authorization source. |
| AzureWAF.Subscription.displayName | String | Subscription display name. |
| AzureWAF.Subscription.id | String | Subscription ID with subscriptions prefix. |
| AzureWAF.Subscription.subscriptionId | String | Subscription ID. |
| AzureWAF.Subscription.locationPlacementId | String | Placmement ID of subscription. |
| AzureWAF.Subscription.tenantId | String | The tenatnt ID of the subscription. |
azure-waf-resource-group-list
Gets all the resource groups for a subscription.
Base Command
azure-waf-resource-group-list
Input
| Argument Name | Description | Required |
|---|---|---|
| subscription_id | The subscription ID. If not provided, the integration default subscription ID will be used. | Optional |
| tag | You can filter by tag names and values. For example, to filter for a tag name and value, tagName=tagValue’. | Optional |
| limit | Maximum number of resource groups to fetch. Default is “50”. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| AzureWAF.ResourceGroup.id | String | Resource group ID. |
| AzureWAF.ResourceGroup.location | String | Resource group location. |
| AzureWAF.ResourceGroup.name | String | Resource group name. |
| AzureWAF.ResourceGroup.type | String | Resource group type. |
| AzureWAF.ResourceGroup.properties | String | Resource group properties. |
| AzureWAF.ResourceGroup.tags | String | Resource group tags. |
Configuration parameters
app_id— App IDsubscription_id— Default Subscription ID (required)resource_group_name— Default Resource Group Name (required)auth_type— Authentication Type (required)tenant_id— Tenant IDcredentials— Client Secretredirect_uri— Application redirect URI (for authorization code mode)auth_code— Authorization codemanaged_identities_client_id—azure_ad_endpoint— Azure AD endpointinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (15)
-
azure-waf-auth-completeRun this command to complete the authorization process. Should be used after running the azure_waf-auth-start command.
-
azure-waf-auth-resetRun this command if for some reason you need to rerun the authentication process.
-
azure-waf-auth-startRun this command to start the authorization process and follow the instructions provided in the command results.
-
azure-waf-auth-testTests connectivity to the Azure Web Application Firewall.
-
azure-waf-front-door-policies-listLists all of the Front Door protection policies within a resource group.
-
azure-waf-front-door-policies-list-all-in-subscriptionLists all of the Front Door protection policies within a subscription.
-
azure-waf-front-door-policy-deleteDeletes a Front Door policy.
-
azure-waf-front-door-policy-update-or-createCreates or updates a Front Door policy with a specified rule set name within a resource group.
-
azure-waf-generate-login-urlGenerate the login url used for Authorization code flow.
-
azure-waf-policies-getRetrieves protection policies within a resource group.
-
azure-waf-policies-list-all-in-subscriptionRetrieves all the WAF policies in a subscription.
-
azure-waf-policy-deleteDeletes a policy.
-
azure-waf-policy-update-or-createCreates or updates a policy with a specified rule set name within a resource group.
-
azure-waf-resource-group-listGets all the resource groups for a subscription.
-
azure-waf-subscriptions-listGets all subscriptions for a tenant.
import AzureWAF as waf import demistomock as demisto import pytest API_VERSION_POLICIES = "2025-05-01" API_VERSION_SUBSCRIPTIONS = "2022-12-01" API_VERSION_RESOURCE_GROUPS = "2021-04-01" FRONT_DOOR_API_VERSION = "2022-05-01" GET_COMMAND_DATA = [ ( {"policy_name": "pol1", "verbose": "false", "limit": "10"}, # args, case: default resource_group { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/test/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies/pol1", "params": {"api-version": API_VERSION_POLICIES}, }, # expected ), ( {"verbose": "false", "limit": "10"}, # args, case: list of policies in default resource_group { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/test/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies", "params": {"api-version": API_VERSION_POLICIES}, }, # expected ), ( {"verbose": "true", "limit": "10"}, # args, case: list of policies in default resource_group with full data { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/test/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies", "params": {"api-version": API_VERSION_POLICIES}, }, # expected ), ( {"resource_group_name": ["res1"], "verbose": "false", "limit": "10"}, # args, case: list of policies in custom resource_group { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/res1/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies", "params": {"api-version": API_VERSION_POLICIES}, }, # expected ), ] @pytest.mark.parametrize("demisto_args,expected_results", GET_COMMAND_DATA) def test_get_policy_by_resource_body(mocker, demisto_args, expected_results): """ Given: - search task's argument When: - retrieving policy's data Then: - validating the body sent to request is matching the search """ mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) m = mocker.patch.object(client, "http_request", return_value={"properties": {"test": "test"}}) waf.policies_get_command(client, **demisto_args) assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("method") == expected_results.get("method") def test_get_array_policy_with_exception(mocker): """ Given: - search task's argument When: - retrieving policy's data Then: - validating the body sent to request is matching the search """ demisto_args = { "policy_name": "pol1", "resource_group_name": ["res1", "res2"], "verbose": "false", "limit": "10", "subscription_id": "sub1", } expected_results = { "method": "GET", "full_url": "https://management.azure.com/subscriptions/sub1/resourceGroups/res2/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies/pol1", "params": {"api-version": API_VERSION_POLICIES}, } client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) side_effect = [Exception("Test"), {"properties": {"test2": "test2"}}] expected_outputs = [{"properties": "res1 threw Exception: Test"}, {"properties": {"test2": "test2"}}] m = mocker.patch.object(client, "http_request", side_effect=side_effect) commandResult = waf.policies_get_command(client, **demisto_args) assert commandResult.outputs == expected_outputs assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("params") == expected_results.get("params") UPSERT_COMMAND_DATA = [ ( { "policy_name": "pol1", "resource_group_name": ["res1"], "verbose": "false", "limit": "10", "managed_rules": '{"test": "test"}', "location": "east", }, # args, case: custom resource_group update rule { "method": "PUT", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/res1/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies/pol1", "params": {"api-version": API_VERSION_POLICIES}, "body": {"location": "east", "properties": {"managedRules": {"test": "test"}}}, }, # expected ), ( { "policy_name": "pol1", "resource_group_name": ["res1"], "verbose": "false", "limit": "10", "managed_rules": '{"test": "test"}', "custom_rules": '{"test": "test"}', "location": "east", }, # args, case: custom resource_group update rule with key hierarchy { "method": "PUT", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/res1/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies/pol1", "params": {"api-version": API_VERSION_POLICIES}, "body": {"location": "east", "properties": {"customRules": {"test": "test"}, "managedRules": {"test": "test"}}}, }, # expected ), ] @pytest.mark.parametrize("demisto_args,expected_results", UPSERT_COMMAND_DATA) def test_policy_upsert_request_body_happy(mocker, demisto_args, expected_results): """ Given: - a policy to update or a new policy When: - updating or creating policy's data Then: - validating the body sent to request is matching the api requires """ mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) m = mocker.patch.object(client, "http_request", return_value={"name": "pol1", "id": "id", "properties": {}}) waf.policy_upsert_command(client, **demisto_args) assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("data") == expected_results.get("body") assert m.call_args[1].get("params") == expected_results.get("params") def test_policy_array_group_names_upsert_request(mocker): """ Given: - a policy to update or a new policy When: - updating or creating policy's data Then: - validating the body sent to request is matching the api requires """ demisto_args = { "policy_name": "pol1", "resource_group_name": ["res1", "res2"], "verbose": "false", "limit": "10", "managed_rules": '{"test": "test"}', "custom_rules": '{"test": "test"}', "location": "east", } expected_results = { "method": "PUT", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/res2/providers/Microsoft.Network/\ ApplicationGatewayWebApplicationFirewallPolicies/pol1", "params": {"api-version": API_VERSION_POLICIES}, "body": { "location": "east", "properties": { "customRules": {"test": "test"}, "managedRules": {"test": "test"}, }, }, } mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) expected_commandResult_output = [{"properties": "res1 threw Exception: Test"}, {"name": "pol1", "id": "id", "properties": {}}] m = mocker.patch.object( client, "http_request", side_effect=[Exception("Test"), {"name": "pol1", "id": "id", "properties": {}}] ) commandResult = waf.policy_upsert_command(client, **demisto_args) assert commandResult.outputs == expected_commandResult_output assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("data") == expected_results.get("body") assert m.call_args[1].get("params") == expected_results.get("params") UPSERT_COMMAND_DATA_BAD_CASES = [ ( { "resource_group_name": "res1", "managed_rules": '{"test": "test"}', "location": "east", "verbose": "false", "limit": "10", }, # args, case: missing policy name "In order to add/ update policy, please provide policy_name, location and managed_rules. ", # expected ), ( {"policy_name": "pol1", "resource_group_name": "res1", "location": "east"}, # args, case: missing managed_rules "In order to add/ update policy, please provide policy_name, location and managed_rules. ", # expected ), ( { "policy_name": "pol1", "resource_group_name": "res1", "managed_rules": '{"test": "test"}', }, # args, case: missing location "In order to add/ update policy, please provide policy_name, location and managed_rules. ", # expected ), ] @pytest.mark.parametrize("demisto_args,expected_error_msg", UPSERT_COMMAND_DATA_BAD_CASES) def test_policy_upsert_request_body_fails(mocker, demisto_args, expected_error_msg): """ Given: - a policy to update or a new policy When: - updating or creating policy's data without policy_name, location or managed_rules. Then: - failing when missing required data """ mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) mocker.patch.object(client, "http_request", return_value={}) with pytest.raises(Exception) as e: waf.policy_upsert_command(client, **demisto_args) assert str(e.value) == expected_error_msg @pytest.mark.parametrize( "params, expected_results", [ ({"auth_type": "Device Code"}, "When using Device Code flow configuration"), ({"auth_type": "Authorization Code"}, "When using Authorization Code flow configuration"), ], ) def test_test_module_command(mocker, params, expected_results): """ Given: - Case 1: Integration params with 'Device' as auth_type. - Case 2: Integration params with 'User Auth' as auth_type. When: - Calling test-module command. Then - Assert the right exception was thrown. - Case 1: Should throw an exception related to Device-code-flow config and return True. - Case 2: Should throw an exception related to User-Auth-flow config and return True. """ mocker.patch.object(waf, "test_connection", side_effect=Exception("mocked error")) mocker.patch.object(demisto, "params", return_value=params) with pytest.raises(Exception) as e: waf.test_module(None, {}) assert expected_results in str(e.value) @pytest.mark.parametrize(argnames="client_id", argvalues=["test_client_id", None]) def test_test_module_command_with_managed_identities(mocker, requests_mock, client_id): """ Given: - Managed Identities client id for authentication. When: - Calling test_module. Then: - Ensure the output are as expected. """ import AzureWAF from AzureWAF import MANAGED_IDENTITIES_TOKEN_URL, Resources, main mock_token = {"access_token": "test_token", "expires_in": "86400"} get_mock = requests_mock.get(MANAGED_IDENTITIES_TOKEN_URL, json=mock_token) params = {"managed_identities_client_id": {"password": client_id}, "auth_type": "Azure Managed Identities"} mocker.patch.object(demisto, "params", return_value=params) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(AzureWAF, "return_results", return_value=params) mocker.patch("MicrosoftApiModule.get_integration_context", return_value={}) main() assert "ok" in AzureWAF.return_results.call_args[0][0] qs = get_mock.last_request.qs assert qs["resource"] == [Resources.management_azure] assert (client_id and qs["client_id"] == [client_id]) or "client_id" not in qs def test_generate_login_url(mocker): """ Given: - Self-deployed are true and auth code are the auth flow When: - Calling function azure-waf-generate-login-url - Ensure the generated url are as expected. """ # prepare import AzureWAF import demistomock as demisto from AzureWAF import Scopes, main redirect_uri = "redirect_uri" tenant_id = "tenant_id" client_id = "client_id" mocked_params = { "redirect_uri": redirect_uri, "auth_type": "Authorization Code", "self_deployed": "True", "tenant_id": tenant_id, "app_id": client_id, "credentials": {"password": "client_secret"}, } mocker.patch.object(demisto, "params", return_value=mocked_params) mocker.patch.object(demisto, "command", return_value="azure-waf-generate-login-url") mocker.patch.object(AzureWAF, "return_results") # call main() # assert expected_url = ( f"[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?" f"response_type=code&scope=offline_access%20{Scopes.management_azure}" f"&client_id={client_id}&redirect_uri={redirect_uri})" ) res = AzureWAF.return_results.call_args[0][0].readable_output assert expected_url in res def test_subscriptions_list_command(mocker): client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) expected_results = { "method": "GET", "full_url": "https://management.azure.com/subscriptions", "params": {"api-version": API_VERSION_SUBSCRIPTIONS}, } m = mocker.patch.object( client, "http_request", return_value={ "value": [ { "id": "/subscriptions/0f907ea4-bc8b-4c11-9d7e-805c2fd144fb", "authorizationSource": "Legacy, RoleBased", "managedByTenants": [], "subscriptionId": "0f907ea4-bc8b-4c11-9d7e-805c2fd144fb", "tenantId": "ebac1a16-81bf-449b-8d43-5732c3c1d999", "displayName": "Pay-As-You-Go", "state": "Enabled", "subscriptionPolicies": { "locationPlacementId": "Public_2014-09-01", "quotaId": "PayAsYouGo_2014-09-01", "spendingLimit": "Off", }, }, { "id": "/subscriptions/057b1785-fd7b-4ca3-ad1b-709e4b1668be", "authorizationSource": "RoleBased", "managedByTenants": [], "subscriptionId": "057b1785-fd7b-4ca3-ad1b-709e4b1668be", "tenantId": "ebac1a16-81bf-449b-8d43-5732c3c1d999", "displayName": "Access to Azure Active Directory", "state": "Enabled", "subscriptionPolicies": { "locationPlacementId": "Public_2014-09-01", "quotaId": "AAD_2015-09-01", "spendingLimit": "On", }, }, ] }, ) commandResult = waf.subscriptions_list_command(client) assert commandResult.readable_output == ( "### Subscriptions: \n" "|displayName|state|subscriptionId|tenantId|\n" "|---|---|---|---|\n" "| Pay-As-You-Go | Enabled | 0f907ea4-bc8b-4c11-9d7e-805c2fd144fb | ebac1a16-81bf-449b-8d43-5732c3c1d999 |\n" "| Access to Azure Active Directory | Enabled | 057b1785-fd7b-4ca3-ad1b-709e4b1668be |" " ebac1a16-81bf-449b-8d43-5732c3c1d999 |\n" ) assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("params") == expected_results.get("params") # Front Door WAF Policy Tests FRONT_DOOR_GET_COMMAND_DATA = [ ( {"policy_name": "fd_pol1", "verbose": "false", "limit": "10"}, # args, case: default resource_group { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/test/providers/Microsoft.Network/\ FrontDoorWebApplicationFirewallPolicies/fd_pol1", "params": {"api-version": FRONT_DOOR_API_VERSION}, }, # expected ), ( {"verbose": "false", "limit": "10"}, # args, case: list of policies in default resource_group { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/test/providers/Microsoft.Network/\ FrontDoorWebApplicationFirewallPolicies", "params": {"api-version": FRONT_DOOR_API_VERSION}, }, # expected ), ( {"resource_group_name": ["fd_res1"], "verbose": "false", "limit": "10"}, # args, case: list of policies in custom resource_group { "method": "GET", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/fd_res1/providers/Microsoft.Network/\ FrontDoorWebApplicationFirewallPolicies", "params": {"api-version": FRONT_DOOR_API_VERSION}, }, # expected ), ] @pytest.mark.parametrize("demisto_args,expected_results", FRONT_DOOR_GET_COMMAND_DATA) def test_front_door_get_policy_by_resource_body(mocker, demisto_args, expected_results): """ Given: - search task's argument for Front Door policy When: - retrieving Front Door policy's data Then: - validating the body sent to request is matching the search """ mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) m = mocker.patch.object(client, "http_request", return_value={"properties": {"test": "test"}}) waf.front_door_policies_list_command(client, **demisto_args) assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("params") == expected_results.get("params") def test_front_door_get_array_policy_with_exception(mocker): """ Given: - search task's argument for Front Door policy When: - retrieving Front Door policy's data with multiple resource groups Then: - validating the body sent to request is matching the search and handles exceptions """ demisto_args = { "policy_name": "fd_pol1", "resource_group_name": ["fd_res1", "fd_res2"], "verbose": "false", "limit": "10", "subscription_id": "sub1", } expected_results = { "method": "GET", "full_url": "https://management.azure.com/subscriptions/sub1/resourceGroups/fd_res2/providers/Microsoft.Network/\ FrontDoorWebApplicationFirewallPolicies/fd_pol1", "params": {"api-version": FRONT_DOOR_API_VERSION}, } client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) side_effect = [Exception("Test"), {"properties": "test2"}] expected_outputs = [{"properties": "fd_res1 threw Exception: Test"}, {"properties": "test2"}] m = mocker.patch.object(client, "http_request", side_effect=side_effect) commandResult = waf.front_door_policies_list_command(client, **demisto_args) assert commandResult.outputs == expected_outputs assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("params") == expected_results.get("params") def test_front_door_policies_list_all_in_subscription_command(mocker): """ Given: - subscription_id argument When: - listing all Front Door policies in subscription Then: - validating the request is correct """ demisto_args = {"verbose": "false", "limit": "10", "subscription_id": "sub1"} client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) m = mocker.patch.object(client, "http_request", return_value={"value": [{"name": "policy1", "id": "id1"}]}) commandResult = waf.front_door_policies_list_all_in_subscription_command(client, **demisto_args) assert "FrontDoorWebApplicationFirewallPolicies" in m.call_args[1].get("full_url") assert m.call_args[1].get("method") == "GET" assert m.call_args[1].get("params") == {"api-version": FRONT_DOOR_API_VERSION} assert commandResult.outputs_prefix == "AzureWAF.FrontDoorPolicy" FRONT_DOOR_UPSERT_COMMAND_DATA = [ ( { "policy_name": "fd_pol1", "resource_group_name": ["fd_res1"], "verbose": "false", "managed_rules": '{"managedRuleSets": [{"ruleSetType": "OWASP", "ruleSetVersion": "3.0"}]}', "location": "global", }, # args, case: custom resource_group update rule { "method": "PUT", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/fd_res1/providers/Microsoft.Network/\ FrontDoorWebApplicationFirewallPolicies/fd_pol1", "params": {"api-version": FRONT_DOOR_API_VERSION}, "body": { "location": "global", "properties": {"managedRules": {"managedRuleSets": [{"ruleSetType": "OWASP", "ruleSetVersion": "3.0"}]}}, "sku": {"name": "Classic_AzureFrontDoor"}, }, }, # expected ), ( { "policy_name": "fd_pol1", "resource_group_name": ["fd_res1"], "verbose": "false", "managed_rules": '{"managedRuleSets": [{"ruleSetType": "OWASP", "ruleSetVersion": "3.0"}]}', "custom_rules": '{"customRules": [{"name": "Rule1", "priority": 1}]}', "location": "global", "sku": "Premium_AzureFrontDoor", }, # args, case: custom resource_group update rule with custom rules and SKU { "method": "PUT", "full_url": "https://management.azure.com/subscriptions/test/resourceGroups/fd_res1/providers/Microsoft.Network/\ FrontDoorWebApplicationFirewallPolicies/fd_pol1", "params": {"api-version": FRONT_DOOR_API_VERSION}, "body": { "location": "global", "properties": { "customRules": {"customRules": [{"name": "Rule1", "priority": 1}]}, "managedRules": {"managedRuleSets": [{"ruleSetType": "OWASP", "ruleSetVersion": "3.0"}]}, }, "sku": {"name": "Premium_AzureFrontDoor"}, }, }, # expected ), ] @pytest.mark.parametrize("demisto_args,expected_results", FRONT_DOOR_UPSERT_COMMAND_DATA) def test_front_door_policy_upsert_request_body_happy(mocker, demisto_args, expected_results): """ Given: - a Front Door policy to update or a new policy When: - updating or creating Front Door policy's data Then: - validating the body sent to request is matching the api requires """ mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) m = mocker.patch.object(client, "http_request", return_value={"name": "fd_pol1", "id": "id", "properties": {}}) waf.front_door_policy_upsert_command(client, **demisto_args) assert m.call_args[1].get("method") == expected_results.get("method") assert m.call_args[1].get("full_url") == expected_results.get("full_url") assert m.call_args[1].get("data") == expected_results.get("body") assert m.call_args[1].get("params") == expected_results.get("params") def test_front_door_policy_array_group_names_upsert_request(mocker): """ Given: - a Front Door policy to update or create with multiple resource groups When: - updating or creating Front Door policy's data across multiple resource groups Then: - validating the body sent to request is matching the API requirements - validating that all resource groups are processed successfully """ demisto_args = { "policy_name": "fd_pol1", "resource_group_name": ["fd_res1", "fd_res2"], "verbose": "false", "managed_rules": '{"managedRuleSets": [{"ruleSetType": "OWASP", "ruleSetVersion": "3.0"}]}', "custom_rules": '{"customRules": [{"name": "Rule1"}]}', "location": "global", } # Expected request body for both resource groups expected_body = { "location": "global", "properties": { "customRules": {"customRules": [{"name": "Rule1"}]}, "managedRules": {"managedRuleSets": [{"ruleSetType": "OWASP", "ruleSetVersion": "3.0"}]}, }, "sku": {"name": "Classic_AzureFrontDoor"}, } # Mock successful responses for both resource groups mock_response_1 = {"name": "fd_pol1", "id": "id1", "properties": {}} mock_response_2 = {"name": "fd_pol1", "id": "id2", "properties": {}} client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) # Mock http_request to return successful responses for both calls m = mocker.patch.object(client, "http_request", side_effect=[mock_response_1, mock_response_2]) # Execute the command commandResult = waf.front_door_policy_upsert_command(client, **demisto_args) # Verify the command returns both results assert commandResult.outputs is not None assert isinstance(commandResult.outputs, list) assert len(commandResult.outputs) == 2 assert commandResult.outputs[0] == mock_response_1 assert commandResult.outputs[1] == mock_response_2 # Verify http_request was called twice (once per resource group) assert m.call_count == 2 # Verify the first call (fd_res1) first_call = m.call_args_list[0][1] assert first_call.get("method") == "PUT" assert "fd_res1" in first_call.get("full_url") assert "FrontDoorWebApplicationFirewallPolicies/fd_pol1" in first_call.get("full_url") assert first_call.get("data") == expected_body assert first_call.get("params") == {"api-version": FRONT_DOOR_API_VERSION} # Verify the second call (fd_res2) second_call = m.call_args_list[1][1] assert second_call.get("method") == "PUT" assert "fd_res2" in second_call.get("full_url") assert "FrontDoorWebApplicationFirewallPolicies/fd_pol1" in second_call.get("full_url") assert second_call.get("data") == expected_body assert second_call.get("params") == {"api-version": FRONT_DOOR_API_VERSION} FRONT_DOOR_UPSERT_COMMAND_DATA_BAD_CASES = [ ( { "resource_group_name": "fd_res1", "managed_rules": '{"test": "test"}', "location": "global", "verbose": "false", }, # args, case: missing policy name "In order to add/update Front Door policy, please provide policy_name and managed_rules.", # expected ), ( {"policy_name": "fd_pol1", "resource_group_name": "fd_res1", "location": "global"}, # args, case: missing managed_rules "In order to add/update Front Door policy, please provide policy_name and managed_rules.", # expected ), ] @pytest.mark.parametrize("demisto_args,expected_error_msg", FRONT_DOOR_UPSERT_COMMAND_DATA_BAD_CASES) def test_front_door_policy_upsert_request_body_fails(mocker, demisto_args, expected_error_msg): """ Given: - a Front Door policy to update or a new policy When: - updating or creating Front Door policy's data without policy_name or managed_rules Then: - failing when missing required data """ mocker.patch.object(demisto, "args", return_value=demisto_args) client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) mocker.patch.object(client, "http_request", return_value={}) with pytest.raises(Exception) as e: waf.front_door_policy_upsert_command(client, **demisto_args) assert str(e.value) == expected_error_msg def test_front_door_policy_delete_command(mocker): """ Given: - policy_name and resource_group_name When: - deleting a Front Door policy Then: - validating the request is correct and returns proper message """ demisto_args = {"policy_name": "fd_pol1", "resource_group_name": ["fd_res1"], "subscription_id": "test"} client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) class MockResponse: status_code = 200 m = mocker.patch.object(client, "http_request", return_value=MockResponse()) mocker.patch.object(demisto, "dt", return_value=None) commandResult = waf.front_door_policy_delete_command(client, **demisto_args) assert "Front Door Policy fd_pol1 was deleted successfully" in commandResult.readable_output assert m.call_args[1].get("method") == "DELETE" assert "FrontDoorWebApplicationFirewallPolicies/fd_pol1" in m.call_args[1].get("full_url") assert m.call_args[1].get("params") == {"api-version": FRONT_DOOR_API_VERSION} def test_front_door_policy_delete_command_not_found(mocker): """ Given: - policy_name for a non-existent Front Door policy When: - deleting a Front Door policy Then: - validating the proper not found message is returned """ demisto_args = {"policy_name": "fd_pol1", "resource_group_name": ["fd_res1"], "subscription_id": "test"} client = waf.AzureWAFClient( app_id="", subscription_id="test", resource_group_name="test", verify=True, proxy=False, auth_type="Device" ) class MockResponse: status_code = 204 mocker.patch.object(client, "http_request", return_value=MockResponse()) mocker.patch.object(demisto, "dt", return_value=None) commandResult = waf.front_door_policy_delete_command(client, **demisto_args) assert "Front Door policy fd_pol1 was deleted or not found." in commandResult.readable_output