Imperva WAF
Use the Imperva WAF integration to manage IP groups and web security policies in Imperva WAF.
Network Security · Imperva WAF
Details
| ID | Imperva WAF |
|---|---|
| Provider | Thales Group |
| Category | Network Security |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Use the Imperva WAF integration to manage IP groups and Web security policies in Imperva WAF.
This integration was integrated and tested with version 14.2 of Imperva WAF and based on Imperva On-Premises WAF (SecureSphere) REST API.
Configure Imperva WAF in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | Server URL (e.g. https://example.net) | True |
| credentials | Username | True |
| insecure | Trust any certificate (not secure) | False |
| proxy | Use system proxy settings | False |
Commands
You can execute these commands from the 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.
imperva-waf-ip-group-list
Get a list of existing IP Group names.
Base Command
imperva-waf-ip-group-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| ImpervaWAF.IpGroup.Name | String | The name of the IP Group |
Command Example
#### Context Example
{
“ImpervaWAF”: {
“IpGroup”: [
{
“Name”: “All Search Engines”
},
{
“Name”: “FireEye Trusted Appliances”
},
{
“Name”: “Bad IP Adresses”
},
{
“Name”: “Google IP Addresses”
}
]
}
}
#### Human Readable Output
>### IP groups
>
>|Name|
>|---|
>| All Search Engines |
>| FireEye Trusted Appliances |
>| Bad IP Adresses |
>| Google IP Addresses |
### imperva-waf-ip-group-list-entries
***
Get a list of the entries in the requested IP group.
#### Base Command
`imperva-waf-ip-group-list-entries`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| ip-group-name | The name of the IP Group | Required |
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.IpGroup.Entries.Type | String | Type of address \(Single, range or network\) |
| ImpervaWAF.IpGroup.Entries.CidrMask | Number | Network significant bits |
| ImpervaWAF.IpGroup.Entries.NetworkAddress | String | Network address |
| ImpervaWAF.IpGroup.Entries.IpAddressTo | String | End IP address |
| ImpervaWAF.IpGroup.Entries.IpAddressFrom | String | Start IP address |
#### Command Example
```!imperva-waf-ip-group-list-entries ip-group-name=`Google IP Addresses````
#### Context Example
{
“ImpervaWAF”: {
“IpGroup”: {
“Entries”: [
{
“CidrMask”: null,
“IpAddressFrom”: “1.2.3.4”,
“IpAddressTo”: “2.3.4.5”,
“NetworkAddress”: null,
“Type”: “range”
},
{
“CidrMask”: null,
“IpAddressFrom”: “1.2.3.4”,
“IpAddressTo”: “2.3.4.5”,
“NetworkAddress”: null,
“Type”: “range”
},
{
“CidrMask”: null,
“IpAddressFrom”: “2.3.4.5”,
“IpAddressTo”: “2.3.4.5”,
“NetworkAddress”: null,
“Type”: “range”
}
],
“Name”: “Google IP Addresses”
}
}
}
#### Human Readable Output
>### IP group entries for Google IP Addresses
>
>|Type|IpAddressFrom|IpAddressTo|
>|---|---|---|
>| range | 1.2.3.4 | 2.3.4.5 |
>| range | 1.2.3.4 | 2.3.4.5 |
>| range | 1.2.3.4 | 2.3.4.5 |
### imperva-waf-ip-group-remove-entries
***
Remove all the entries from an IP Group indicated by group name.
#### Base Command
`imperva-waf-ip-group-remove-entries`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| ip-group-name | The name of the IP Group | Required |
#### Context Output
There is no context output for this command.
#### Command Example
```!imperva-waf-ip-group-remove-entries ip-group-name=`test_policy````
#### Context Example
{}
#### Human Readable Output
>The IP group test_policy is now empty
### imperva-waf-sites-list
***
Returns a list of the names of all sites in the system.
#### Base Command
`imperva-waf-sites-list`
#### Input
There are no input arguments for this command.
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.Site.Name | String | The name of the site |
#### Command Example
```!imperva-waf-sites-list```
#### Context Example
{
“ImpervaWAF”: {
“Site”: {
“Name”: “Default Site”
}
}
}
#### Human Readable Output
>### All sites in the system
>
>|Name|
>|---|
>| Default Site |
### imperva-waf-server-group-list
***
Returns a list of all server group names under the site.
#### Base Command
`imperva-waf-server-group-list`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| site-name | The name of the site | Required |
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.ServerGroup.Name | String | The name of the server group |
| ImpervaWAF.ServerGroup.SiteName | String | The name of the parent site of the server groups to access |
#### Command Example
```!imperva-waf-server-group-list site-name=`Default Site````
#### Context Example
{
“ImpervaWAF”: {
“ServerGroup”: {
“Name”: “Tel Aviv”,
“SiteName”: “Default Site”
}
}
}
#### Human Readable Output
>### Server groups in Default Site
>
>|Name|SiteName|
>|---|---|
>| Tel Aviv | Default Site |
### imperva-waf-server-group-list-policies
***
Get server groups applied web security policies.
#### Base Command
`imperva-waf-server-group-list-policies`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| site-name | Site name | Required |
| server-group-name | Server group name | Required |
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.SecurityPolicy.PolicyName | String | Policy Name |
| ImpervaWAF.SecurityPolicy.PolicyType | String | Policy type |
| ImpervaWAF.SecurityPolicy.ServerGroup | String | Server group name |
| ImpervaWAF.SecurityPolicy.SiteName | String | Site name |
| ImpervaWAF.SecurityPolicy.System | Boolean | FI policy |
#### Command Example
```!imperva-waf-server-group-list-policies site-name=`Default Site` server-group-name=`Tel Aviv````
#### Context Example
{
“ImpervaWAF”: {
“SecurityPolicy”: [
{
“PolicyName”: “Network Protocol Violations Policy”,
“PolicyType”: “NetworkProtocolViolations”,
“ServerGroup”: “Tel Aviv”,
“SiteName”: “Default Site”,
“System”: true
},
{
“PolicyName”: “Firewall Policy”,
“PolicyType”: “Firewall”,
“ServerGroup”: “Tel Aviv”,
“SiteName”: “Default Site”,
“System”: true
}
]
}
}
#### Human Readable Output
>### Policies for Tel Aviv
>
>|PolicyName|PolicyType|ServerGroup|SiteName|System|
>|---|---|---|---|---|
>| Network Protocol Violations Policy | NetworkProtocolViolations | Tel Aviv | Default Site | true |
>| Firewall Policy | Firewall | Tel Aviv | Default Site | true |
### imperva-waf-web-service-custom-policy-list
***
Returns a list of names of all Web Application Custom Policies in the system.
#### Base Command
`imperva-waf-web-service-custom-policy-list`
#### Input
There are no input arguments for this command.
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.CustomWebPolicy.Name | String | The name of the policy |
#### Command Example
```!imperva-waf-web-service-custom-policy-list```
#### Context Example
{
“ImpervaWAF”: {
“CustomWebPolicy”: [
{
“Name”: “HTML Injection”
},
{
“Name”: “OS Commands injection”
},
{
“Name”: “Malicious File Upload”
},
{
“Name”: “ThreatRadar - Emergency - GET Requests”
},
{
“Name”: “ThreatRadar - Emergency - POST Requests”
},
{
“Name”: “ThreatRadar - Emergency - Authenticated Sessions”
},
{
“Name”: “Sensitive Error Messages Leakage”
}
]
}
}
#### Human Readable Output
>### Custom web policies
>
>|Name|
>|---|
>| HTML Injection |
>| OS Commands injection |
>| Malicious File Upload |
>| ThreatRadar - Emergency - GET Requests |
>| ThreatRadar - Emergency - POST Requests |
>| ThreatRadar - Emergency - Authenticated Sessions |
>| ThreatRadar - Emergency - Authenticated Sessions |
>| Sensitive Error Messages Leakage |
### imperva-waf-web-service-custom-policy-get
***
Returns a Web Application Custom Policy indicated by policy name.
#### Base Command
`imperva-waf-web-service-custom-policy-get`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| policy-name | The name of the policy | Required |
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.CustomWebPolicy.Enabled | Boolean | Whether the policy is enabled |
| ImpervaWAF.CustomWebPolicy.FollowedAction | String | Name of the Action Set |
| ImpervaWAF.CustomWebPolicy.Name | String | The name of the policy |
| ImpervaWAF.CustomWebPolicy.OneAlertPerSession | Boolean | Indicates whether to allow only one alert to be created for every web session |
| ImpervaWAF.CustomWebPolicy.DisplayResponsePage | Boolean | Indicates whether to show response page in alerts |
| ImpervaWAF.CustomWebPolicy.Action | String | Policy Action |
| ImpervaWAF.CustomWebPolicy.Severity | String | Alert Severity |
| ImpervaWAF.CustomWebPolicy.ApplyTo.serverGroupName | String | Name of the server group to apply |
| ImpervaWAF.CustomWebPolicy.ApplyTo.siteName | String | Name of the site to apply |
| ImpervaWAF.CustomWebPolicy.ApplyTo.webServiceName | String | Name of the web service to apply |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.operation | String | Match operation for values |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.type | String | Match Criterion name |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.ipGroups.Group name | String | Name of IP Group to search in |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.userDefined.IP Address | String | IP address to search in |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.values.country | String | Country name to match |
#### Command Example
```!imperva-waf-web-service-custom-policy-get policy-name=`Suspicious File Extension Access````
#### Context Example
{
“ImpervaWAF”: {
“CustomWebPolicy”: {
“Action”: “none”,
“ApplyTo”: [
{
“serverGroupName”: “Tel Aviv”,
“siteName”: “Default Site”,
“webServiceName”: “Orders”
}
],
“DisplayResponsePage”: false,
“Enabled”: true,
“FollowedAction”: null,
“MatchCriteria”: [
{
“operation”: “atLeastOne”,
“type”: “httpRequestFileExtension”,
“values”: [
“.swp”,
“.sqlite”,
“.pem”,
“.bp”,
“.conf”,
“.der”,
“.ini”,
“.git”,
“.db”,
“.svn”,
“.core”,
“.DS_Store”,
“.raw”,
“.dmp”,
“.log”,
“.pkcs12”,
“.bak”,
“.pfx.p12”
]
}
],
“Name”: “Suspicious File Extension Access”,
“OneAlertPerSession”: false,
“Severity”: “high”
}
}
}
#### Human Readable Output
>### Policy data for Suspicious File Extension Access
>
>|Action|DisplayResponsePage|Enabled|Name|OneAlertPerSession|Severity|
>|---|---|---|---|---|---|
>| none | false | true | Suspicious File Extension Access | false | high |
>
>
>### Services to apply the policy to
>
>|serverGroupName|siteName|webServiceName|
>|---|---|---|
>| Tel Aviv | Default Site | Orders |
### imperva-waf-ip-group-create
***
Create an IP Group.
#### Base Command
`imperva-waf-ip-group-create`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| group-name | Group name to create | Required |
| entry-type | Type of address (Single, range or network) | Required |
| ip-address-from | Start IP address, Mandatory for types: single, range | Optional |
| ip-address-to | End IP address, Mandatory for type: range | Optional |
| network-address | Network address, Mandatory for type: network | Optional |
| cidr-mask | Network significant bits, Mandatory for type: network | Optional |
| json-entries | List of entries values in json format, e.g. [{"type":"single","ipAddressFrom":"1.2.3.4"}] | Optional |
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.IpGroup.Name | String | The name of the IP Group |
#### Command Example
```!imperva-waf-ip-group-create group-name=`test_policy` entry-type=range ip-address-from=127.0.0.1 ip-address-to=127.0.0.2```
#### Context Example
{
“ImpervaWAF”: {
“IpGroup”: {
“Name”: “test_policy”
}
}
}
#### Human Readable Output
>Group test_policy created successfully
### imperva-waf-ip-group-update-entries
***
Add or remove rows in an IP Group indicated by ip Group Name.
#### Base Command
`imperva-waf-ip-group-update-entries`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| group-name | Group name to update | Required |
| entry-type | Type of address (Single, range or network) | Required |
| ip-address-from | Start IP address, Mandatory for types: single, range | Optional |
| ip-address-to | End IP address, Mandatory for type: range | Optional |
| network-address | Network address, Mandatory for type: network | Optional |
| cidr-mask | Network significant bits, Mandatory for type: network | Optional |
| operation | Operation to apply on the entry | Required |
| json-entries | List of entries values in json format, e.g. [{"operation":"add","type":"single","ipAddressFrom":"1.2.3.4"}] | Optional |
#### Context Output
There is no context output for this command.
#### Command Example
```!imperva-waf-ip-group-update-entries group-name=test_policy entry-type=range ip-address-from=10.0.0.1 ip-address-to=10.0.0.2 operation=add```
#### Context Example
{}
#### Human Readable Output
>Group test_policy updated successfully
### imperva-waf-ip-group-delete
***
Delete a IP Group indicated by group name.
#### Base Command
`imperva-waf-ip-group-delete`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| group-name | Group name to delete | Required |
#### Context Output
There is no context output for this command.
#### Command Example
```!imperva-waf-ip-group-delete group-name=test_policy```
#### Context Example
{}
#### Human Readable Output
>Group test_policy deleted successfully
### imperva-waf-web-service-custom-policy-create
***
Create a Web Service Custom Policy.
#### Base Command
`imperva-waf-web-service-custom-policy-create`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| policy-name | The name of the policy to create | Required |
| enabled | Whether the policy is enabled, Default: True | Optional |
| severity | Alert Severity, Default: medium | Optional |
| action | Policy Action, Default: none | Optional |
| followed-action | Name of the Action Set | Optional |
| one-alert-per-session | Indicates whether to allow only one alert to be created for every web session, Default: False | Optional |
| display-response-page | Indicates whether to show the response page in alerts, Default: False | Optional |
| site-name-to-apply | Name of the site to apply | Required |
| server-group-name-to-apply | Name of the server group to apply | Required |
| web-service-name-to-apply | Name of the web service to apply | Required |
| geo-location-criteria-operation | Match operation for Source Geolocation | Optional |
| ip-groups | Comma separated list of names of IP Groups to search in | Optional |
| ip-addresses | Comma separated list of IP addresses to search in | Optional |
| country-names | Comma separated list of country names to search in, mandatory when geo-location-criteria-operation is set | Optional |
| ip-addresses-criteria-operation | Match operation for Source IP addresses | Optional |
| match-criteria-json | List of match criteria in json format, e.g. [{"type": "sourceIpAddresses","operation": "atLeastOne","userDefined": ["1.2.3.4"]}] | Optional |
#### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| ImpervaWAF.CustomWebPolicy.Enabled | Boolean | Indicates whether the policy is enabled. |
| ImpervaWAF.CustomWebPolicy.FollowedAction | String | The name of the action set. |
| ImpervaWAF.CustomWebPolicy.Name | String | The name of the policy. |
| ImpervaWAF.CustomWebPolicy.OneAlertPerSession | Boolean | Indicates whether to allow only one alert to be created for every web session. |
| ImpervaWAF.CustomWebPolicy.DisplayResponsePage | Boolean | Indicates whether to show the response page in the alerts. |
| ImpervaWAF.CustomWebPolicy.Action | String | The custom web policy action. |
| ImpervaWAF.CustomWebPolicy.Severity | String | The custom web policy alert severity. |
| ImpervaWAF.CustomWebPolicy.ApplyTo.serverGroupName | String | The name of the server group to apply. |
| ImpervaWAF.CustomWebPolicy.ApplyTo.siteName | String | The name of the site to apply. |
| ImpervaWAF.CustomWebPolicy.ApplyTo.webServiceName | String | The name of the web service to apply. |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.operation | String | The match operation for values. |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.type | String | The match criterion name. |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.ipGroups.Group name | String | The name of the IP group in which to search. |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.userDefined.IP Address | String | The IP address in which to search. |
| ImpervaWAF.CustomWebPolicy.MatchCriteria.values.country | String | Country name to match. |
#### Command Example
```!imperva-waf-web-service-custom-policy-create policy-name=test_policy server-group-name-to-apply=`Tel Aviv` site-name-to-apply=`Default Site` web-service-name-to-apply=Orders followed-action=`Long IP Block````
#### Context Example
{}
#### Human Readable Output
>Policy test_policy created successfully
### imperva-waf-web-service-custom-policy-update
***
Update a Web Service Custom Policy.
#### Base Command
`imperva-waf-web-service-custom-policy-update`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| policy-name | The name of the policy to update | Required |
| enabled | Whether the policy is enabled | Optional |
| severity | Alert Severity | Optional |
| action | Policy Action | Optional |
| followed-action | Name of the Action Set | Optional |
| one-alert-per-session | Indicates whether to allow only one alert to be created for every web session | Optional |
| display-response-page | Indicates whether to show the response page in alerts | Optional |
| site-name-to-apply | Name of the site to apply | Optional |
| server-group-name-to-apply | Name of the server group to apply | Optional |
| web-service-name-to-apply | Name of the web service to apply | Optional |
| geo-location-criteria-operation | Match operation for Source Geolocation | Optional |
| ip-groups | Comma separated list of names of IP Groups to search in | Optional |
| ip-addresses | Comma separated list of IP addresses to search in | Optional |
| country-names | Comma separated list of country names to search in, mandatory when geo-location-criteria-operation is set | Optional |
| ip-addresses-criteria-operation | Match operation for Source IP addresses | Optional |
| apply-operation | Operation to apply | Optional |
| match-criteria-json | List of match criteria in json format, e.g. [{"type":"sourceIpAddresses","operation":"atLeastOne","userDefined":["1.2.3.4"]}] | Optional |
#### Context Output
There is no context output for this command.
#### Command Example
```!imperva-waf-web-service-custom-policy-update policy-name=test_policy enabled=False```
#### Context Example
{}
#### Human Readable Output
>Policy test_policy updated successfully
### imperva-waf-web-service-custom-policy-delete
***
Delete a Web Service Custom Policy indicated by policy name.
#### Base Command
`imperva-waf-web-service-custom-policy-delete`
#### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| policy-name | The name of the policy to delete | Required |
#### Context Output
There is no context output for this command.
#### Command Example
```!imperva-waf-web-service-custom-policy-delete policy-name=`test_policy````
#### Context Example
{}
```
Human Readable Output
Policy test_policy deleted successfully
Configuration parameters
url— Server URL (e.g., https://example.net) (required)credentials— Username (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (14)
-
imperva-waf-ip-group-createCreate an IP group.
-
imperva-waf-ip-group-deleteDeletes the IP group indicated by the group name.
-
imperva-waf-ip-group-listGets a list of the existing IP group names.
-
imperva-waf-ip-group-list-entriesReturns a list of the entries in the requested IP group.
-
imperva-waf-ip-group-remove-entriesRemoves all the entries from the IP group indicated by the group name.
-
imperva-waf-ip-group-update-entriesAdds or removes rows in the IP group indicated by the IP group name.
-
imperva-waf-server-group-listReturns a list of all server group names in the specified site.
-
imperva-waf-server-group-list-policiesReturns a list of the server groups that applied the web security policies.
-
imperva-waf-sites-listReturns a list of the names of all sites in the system.
-
imperva-waf-web-service-custom-policy-createCreate a web service custom policy.
-
imperva-waf-web-service-custom-policy-deleteDeletes a web service custom policy indicated by the policy name.
-
imperva-waf-web-service-custom-policy-getReturns a web service custom policy indicated by the policy name.
-
imperva-waf-web-service-custom-policy-listReturns a list of names of all web service custom policies in the system.
-
imperva-waf-web-service-custom-policy-updateUpdate a web service custom policy.
import demistomock as demisto from CommonServerPython import * from CommonServerUserPython import * """ IMPORTS """ import json import traceback import urllib3 # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ INTEGRATION_CONTEXT_NAME = "ImpervaWAF" class Client(BaseClient): """ Client will implement the service API, and should not contain any Demisto logic. Should only do requests and return data. """ session_id = "" def do_request(self, method, url_suffix, json_data=None): if not self.session_id: self.login() res = self._http_request( method, f"SecureSphere/api/v1/{url_suffix}", json_data=json_data, headers={"Cookie": self.session_id}, ok_codes=(200, 401, 406), resp_type="response", ) if res.status_code == 401: self.login() res = self._http_request( method, f"SecureSphere/api/v1/{url_suffix}", json_data=json_data, headers={"Cookie": self.session_id}, ok_codes=(200, 401, 406), resp_type="response", ) if res.text: res = res.json() else: res = {} extract_errors(res) return res def login(self): res = self._http_request("POST", "SecureSphere/api/v1/auth/session", auth=self._auth) extract_errors(res) self.session_id = res.get("session-id") def get_ip_group_entities(self, group_name, table_name): raw_res = self.do_request("GET", f"conf/ipGroups/{group_name}") entries = [] for entry in raw_res.get("entries"): entries.append( { "Type": entry.get("type"), "IpAddressFrom": entry.get("ipAddressFrom"), "IpAddressTo": entry.get("ipAddressTo"), "NetworkAddress": entry.get("networkAddress"), "CidrMask": entry.get("cidrMask"), } ) human_readable = tableToMarkdown( table_name, entries, removeNull=True, headers=["Type", "IpAddressFrom", "IpAddressTo", "NetworkAddress", "CidrMask"] ) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.IpGroup(val.Name===obj.Name)": {"Name": group_name, "Entries": entries}} return human_readable, entry_context, raw_res def get_custom_policy_outputs(self, policy_name, table_name): raw_res = self.do_request("GET", f"conf/policies/security/webServiceCustomPolicies/{policy_name}") policy = { "Name": policy_name, "Enabled": raw_res.get("enabled"), "OneAlertPerSession": raw_res.get("oneAlertPerSession"), "DisplayResponsePage": raw_res.get("displayResponsePage"), "Severity": raw_res.get("severity"), "Action": raw_res.get("action"), "FollowedAction": raw_res.get("followedAction"), "ApplyTo": raw_res.get("applyTo"), "MatchCriteria": raw_res.get("matchCriteria"), } hr_policy = policy.copy() del hr_policy["MatchCriteria"] del hr_policy["ApplyTo"] human_readable = tableToMarkdown(table_name, hr_policy, removeNull=True) if raw_res.get("applyTo"): human_readable += "\n\n" + tableToMarkdown("Services to apply the policy to", raw_res.get("applyTo"), removeNull=True) for match in raw_res.get("matchCriteria", []): tmp_match = match.copy() operation = match["operation"] match_type = match["type"] # generate human readable for sourceIpAddresses type if match_type == "sourceIpAddresses": if tmp_match.get("userDefined"): for i, _element in enumerate(tmp_match["userDefined"]): tmp_match["userDefined"][i] = {"IP Address": tmp_match["userDefined"][i]} human_readable += "\n\n" + tableToMarkdown( f"Match operation: {operation}\n Source IP addresses:", tmp_match["userDefined"], removeNull=True ) if tmp_match.get("ipGroups"): for i, _element in enumerate(tmp_match["ipGroups"]): tmp_match["ipGroups"][i] = {"Group name": tmp_match["ipGroups"][i]} human_readable += "\n\n" + tableToMarkdown( f"Match operation: {operation}\n IP Groups:", tmp_match["ipGroups"], removeNull=True ) # generate human readable for sourceGeolocation type elif match_type == "sourceGeolocation": if tmp_match.get("values"): for i, _element in enumerate(tmp_match["values"]): tmp_match["values"][i] = {"Country name": tmp_match["values"][i]} human_readable += "\n\n" + tableToMarkdown( f"Match operation: {operation}\n Countries to match:", tmp_match["values"], removeNull=True ) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.CustomWebPolicy(val.Name===obj.Name)": policy} return human_readable, entry_context, raw_res def extract_errors(res): if not isinstance(res, list) and res.get("errors"): error_message = "" for err in res["errors"]: error_message += f'error-code: {err.get("error-code")}, description: {err.get("description")}' raise Exception(error_message) def generate_policy_data_body(args): severity = args.get("severity") action = args.get("action") followed_action = args.get("followed-action") body = {} if args.get("enabled"): body["enabled"] = args["enabled"] == "True" if args.get("one-alert-per-session"): body["oneAlertPerSession"] = args["one-alert-per-session"] == "True" if args.get("display-response-page"): body["displayResponsePage"] = args["display-response-page"] == "True" if severity: body["severity"] = severity if action: body["action"] = action if followed_action: body["followedAction"] = followed_action return body def generate_match_criteria(body, args): geo_location_criteria_operation = args.get("geo-location-criteria-operation") ip_addresses_criteria_operation = args.get("ip-addresses-criteria-operation") ip_groups = args.get("ip-groups", "") ip_addreses = args.get("ip-addresses", "") country_names = args.get("country-names", "") match_criteria = [] if geo_location_criteria_operation: if not country_names: raise Exception("country-names argument is empty") geo_location_match_item = { "type": "sourceGeolocation", "operation": geo_location_criteria_operation, "values": country_names.split(","), } match_criteria.append(geo_location_match_item) if ip_addresses_criteria_operation: if not ip_groups and not ip_addreses: raise Exception("ip-groups and ip-addresses arguments are empty, please fill at least one of them") ip_addresses_match_item = {"type": "sourceIpAddresses", "operation": ip_addresses_criteria_operation} if ip_groups: ip_addresses_match_item["ipGroups"] = ip_groups.split(",") if ip_addreses: ip_addresses_match_item["userDefined"] = ip_addreses.split(",") match_criteria.append(ip_addresses_match_item) body["matchCriteria"] = match_criteria return body def generate_ip_groups_entries(args): entry_type = args.get("entry-type") ip_from = args.get("ip-address-from") ip_to = args.get("ip-address-to") network_address = args.get("network-address") cidr_mask = args.get("cidr-mask") operation = args.get("operation") json_entries = args.get("json-entries") if not json_entries: entry = {} if entry_type == "single": entry["ipAddressFrom"] = ip_from elif entry_type == "range": entry["ipAddressFrom"] = ip_from entry["ipAddressTo"] = ip_to elif entry_type == "network": entry["networkAddress"] = network_address entry["cidrMask"] = cidr_mask else: raise Exception("entry-type argument is invalid") entry["type"] = entry_type entry["operation"] = operation body = {"entries": [entry]} else: try: json_entries = json.loads(json_entries) except Exception: raise Exception(f"Failed to parse json-entries as JSON data, received object:\n{json_entries}") body = {"entries": json_entries} return body @logger def test_module(client, args): raw_res = client.do_request("GET", "conf/sites") if raw_res.get("sites"): demisto.results("ok") @logger def ip_group_list_command(client, args): raw_res = client.do_request("GET", "conf/ipGroups") groups = [] if raw_res.get("names"): groups = raw_res["names"] for i, _element in enumerate(groups): groups[i] = {"Name": groups[i]} human_readable = tableToMarkdown("IP groups", groups, removeNull=True) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.IpGroup(val.Name===obj.Name)": groups} return_outputs(human_readable, entry_context, raw_res) @logger def ip_group_list_entries_command(client, args): group_name = args.get("ip-group-name") human_readable, entry_context, raw_res = client.get_ip_group_entities(group_name, f"IP group entries for {group_name}") return_outputs(human_readable, entry_context, raw_res) @logger def ip_group_remove_entries_command(client, args): group_name = args.get("ip-group-name") raw_res = client.do_request("DELETE", f"conf/ipGroups/{group_name}/clear") return_outputs(f"The IP group {group_name} is now empty", {}, raw_res) @logger def sites_list_command(client, args): raw_res = client.do_request("GET", "conf/sites") sites = [{"Name": site} for site in raw_res.get("sites", [])] human_readable = tableToMarkdown("All sites in the system", sites, removeNull=True) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.Site(val.Name===obj.Name)": sites} return_outputs(human_readable, entry_context, raw_res) @logger def server_groups_list_command(client, args): site = args.get("site-name") raw_res = client.do_request("GET", f"conf/serverGroups/{site}") server_groups = [] if raw_res.get("server-groups"): server_groups = raw_res["server-groups"] for i, _element in enumerate(server_groups): server_groups[i] = {"Name": server_groups[i], "SiteName": site} human_readable = tableToMarkdown(f"Server groups in {site}", server_groups, removeNull=True) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.ServerGroup(val.Name===obj.Name)": server_groups} return_outputs(human_readable, entry_context, raw_res) @logger def server_group_policies_list_command(client, args): site = args.get("site-name") server_group = args.get("server-group-name") raw_res = client.do_request("GET", f"conf/serverGroups/{site}/{server_group}/securityPolicies") policies = [] for policy in raw_res: policies.append( { "System": policy.get("system"), "PolicyName": policy.get("policy-name"), "PolicyType": policy.get("policy-type"), "ServerGroup": server_group, "SiteName": site, } ) human_readable = tableToMarkdown(f"Policies for {server_group}", policies, removeNull=True) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.SecurityPolicy(val.PolicyName===obj.PolicyName)": policies} return_outputs(human_readable, entry_context, raw_res) @logger def custom_policy_list_command(client, args): raw_res = client.do_request("GET", "conf/policies/security/webServiceCustomPolicies") policies = [] if raw_res.get("customWebPolicies"): policies = raw_res["customWebPolicies"] for i, _element in enumerate(policies): policies[i] = {"Name": policies[i]} human_readable = tableToMarkdown("Custom web policies", policies, removeNull=True) entry_context = {f"{INTEGRATION_CONTEXT_NAME}.CustomWebPolicy(val.Name===obj.Name)": policies} return_outputs(human_readable, entry_context, raw_res) @logger def get_custom_policy_command(client, args): policy_name = args.get("policy-name") human_readable, entry_context, raw_res = client.get_custom_policy_outputs(policy_name, f"Policy data for {policy_name}") return_outputs(human_readable, entry_context, raw_res) @logger def create_ip_group_command(client, args): group_name = args.get("group-name") body = generate_ip_groups_entries(args) client.do_request("POST", f"conf/ipGroups/{group_name}", json_data=body) human_readable, entry_context, raw_res = client.get_ip_group_entities(group_name, f"Group {group_name} created successfully") return_outputs(human_readable, entry_context, raw_res) @logger def update_ip_group_command(client, args): group_name = args.get("group-name") body = generate_ip_groups_entries(args) client.do_request("PUT", f"conf/ipGroups/{group_name}/data", json_data=body) human_readable, entry_context, raw_res = client.get_ip_group_entities(group_name, f"Group {group_name} updated successfully") return_outputs(human_readable, entry_context, raw_res) @logger def delete_ip_group_command(client, args): group_name = args.get("group-name") raw_res = client.do_request("DELETE", f"conf/ipGroups/{group_name}") return_outputs(f"Group {group_name} deleted successfully", {}, raw_res) @logger def create_custom_policy_command(client, args): policy_name = args.get("policy-name") site = args.get("site-name-to-apply") server_group = args.get("server-group-name-to-apply") web_service = args.get("web-service-name-to-apply") match_criteria_json = args.get("match-criteria-json") body = generate_policy_data_body(args) if match_criteria_json and not isinstance(match_criteria_json, dict): try: match_criteria_json = json.loads(match_criteria_json) except Exception: raise Exception(f"Failed to parse match-criteria-json as JSON data, received object:\n{match_criteria_json}") body["matchCriteria"] = match_criteria_json else: body = generate_match_criteria(body, args) body["applyTo"] = [{"siteName": site, "serverGroupName": server_group, "webServiceName": web_service}] client.do_request("POST", f"conf/policies/security/webServiceCustomPolicies/{policy_name}", json_data=body) human_readable, entry_context, raw_res = client.get_custom_policy_outputs( policy_name, f"Policy {policy_name} created successfully" ) return_outputs(human_readable, entry_context, raw_res) @logger def update_custom_policy_command(client, args): policy_name = args.get("policy-name") site = args.get("site-name-to-apply") server_group = args.get("server-group-name-to-apply", "") web_service = args.get("web-service-name-to-apply", "") apply_operation = args.get("apply-operation", "") match_criteria_json = args.get("match-criteria-json") body = generate_policy_data_body(args) if match_criteria_json and not isinstance(match_criteria_json, dict): try: match_criteria_json = json.loads(match_criteria_json) except Exception: raise DemistoException(f"Failed to parse match-criteria-json as JSON data, received object:\n{match_criteria_json}") body["matchCriteria"] = match_criteria_json else: body = generate_match_criteria(body, args) if apply_operation: body["applyTo"] = [ {"operation": apply_operation, "siteName": site, "serverGroupName": server_group, "webServiceName": web_service} ] client.do_request("PUT", f"conf/policies/security/webServiceCustomPolicies/{policy_name}", json_data=body) human_readable, entry_context, raw_res = client.get_custom_policy_outputs( policy_name, f"Policy {policy_name} updated successfully" ) return_outputs(human_readable, entry_context, raw_res) @logger def delete_custom_policy_command(client, args): policy_name = args.get("policy-name") raw_res = client.do_request("DELETE", f"conf/policies/security/webServiceCustomPolicies/{policy_name}") return_outputs(f"Policy {policy_name} deleted successfully", {}, raw_res) def main(): params = demisto.params() # get the service API url base_url = params.get("url") verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) credentials = params.get("credentials") username = credentials["identifier"] if credentials else "" password = credentials["password"] if credentials else "" LOG(f"Command being called is {demisto.command()}") try: client = Client(base_url=base_url, verify=verify_certificate, auth=(username, password), proxy=proxy) command = demisto.command() args = demisto.args() commands = { "test-module": test_module, "imperva-waf-ip-group-list": ip_group_list_command, "imperva-waf-ip-group-list-entries": ip_group_list_entries_command, "imperva-waf-ip-group-remove-entries": ip_group_remove_entries_command, "imperva-waf-sites-list": sites_list_command, "imperva-waf-server-group-list": server_groups_list_command, "imperva-waf-server-group-list-policies": server_group_policies_list_command, "imperva-waf-web-service-custom-policy-list": custom_policy_list_command, "imperva-waf-web-service-custom-policy-get": get_custom_policy_command, "imperva-waf-ip-group-create": create_ip_group_command, "imperva-waf-ip-group-update-entries": update_ip_group_command, "imperva-waf-ip-group-delete": delete_ip_group_command, "imperva-waf-web-service-custom-policy-create": create_custom_policy_command, "imperva-waf-web-service-custom-policy-update": update_custom_policy_command, "imperva-waf-web-service-custom-policy-delete": delete_custom_policy_command, } if command in commands: commands[command](client, args) else: raise NotImplementedError(f'Command "{command}" is not implemented.') # Log exceptions except Exception as e: return_error(f"Unexpected error: {e!s}", error=traceback.format_exc()) if __name__ in ("__main__", "__builtin__", "builtins"): main()