The StackPath WAF is highly customizable and can be configured via the Control Panel or through the API. In this article, we'll walk you through how to setup your system to manage the StackPath WAF via the API, and provide examples to get you started.
Attached to this article are the SDK's and Examples provided below for your reference.
Installing pre-requisites
To work with the methods described below, python-pip is required with your Linux setup.
- Once you've installed python-pip:
sudo apt-get install python-pip
- Install the certificate and the requests
sudo pip install requests
sudo pip install certificate
- Download the attached .tar.gz file and extract it, along with creating the waf.php script we'll use for the API calls :
wget https://support.stackpath.com/hc/en-us/article_attachments/115010774486/PHP-SDK.tar.gz&&tar xvzf PHP-SDK.tar.gz&&(echo "<?php";echo "require_once (__DIR__.'/composer/vendor/autoload.php');";echo "";echo "?>") > waf.php
- This will download the needed composer, along with the SDK, and create the waf.php file we'll use for the API calls themselves. Your directory should now contain the composer folder, along with the waf.php script.
Using the SDK
- In order for the API to function, use our SDK, which is attached in this article. For ease of use we recommend placing the StackPath SDK in the same folder as the .py.
- Here is an example of how to alter the SQL Injection policy using our API :
from sdk import StackPath
import json
SPApi = StackPath("alias", "key", "secret")
SPApi.put('/sites/SiteID/waf/policies/W-57900')
For this script to work, replace alias, key and secret with the corresponding values, as well as create the API on this page. The SiteID will also need to be replaced with the ID of the Stackpath Site. In the example used, we used the code W-57900 which corresponds the SQL injection policy.
- In order for the API to function, use our SDK, which is attached in this article. For ease of use we recommend placing the composer folder in the same directory as the .php.
- Here is an example of how to alter the SQL Injection policy using our API :
require_once (__DIR__.'/composer/vendor/autoload.php');
$api = new MaxCDN("alias","key","secret");
$api->put('/sites/SITEID/waf/policies/W-57900');
For this script to work, replace alias, key and secret with the corresponding values, as well as create the API on this page. The SiteID will also need to be replaced with the ID of the Stackpath Site. In the example used, we used the code W-57900 which corresponds the SQL injection policy.
Creating Custom Rules
Custom WAF rules can also be created via the StackPath API. The list of available rules is as follows: IP, IP Range, URL, User Agent, Header, HTTP Method, File Extension, Content Type, Country and rule by Organization.
To create these rules, a POST request must be sent to /sites/SITEID/waf/rules as follows :
SPApi.post('/sites/SITEID/waf/rules',data=OrgBlock)
$OrgBlock = array('name'=>'Organization Block','action'=>'Monitor','active'=>'1','conditions'=>json_encode(array((['scope'=>'Organization','data'=>'Organization Name']))));
Examples of Custom Rules
- Rule by IP
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions on a specific IP.
The Blocked IP, or multiple IPs, in this case is are 192.168.0.1 and 192.168.0.2 separated by a comma.
IPBlock={"name": "IP Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "Ip","data":"192.168.0.1,192.168.0.2"}])}
$IPBlock = array('name'=>'IP Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'Ip','data'=>'192.168.0.1,192.168.0.2']))));
- Rule by IP Range
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions on a specific URL.
The IP Range, in this case is from 192.168.0.1 to 192.168.0.2, separated by a comma.
IPRangeBlock={"name": "IP Range Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "IpRange","data":"192.168.0.1,192.168.0.2"}])}
$IPRangeBlock = array('name'=>'IP Range Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'IpRange','data'=>'192.168.0.1,192.168.0.2']))));
- Rule by URL
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions on a specific URL.
The Blocked URL, or to be more specific URI, in this case is /blocked.html
URLBlock={"name": "URL Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "Url","data":"/blocked.html","function":"Contains"}])}
$URLBlock = array('name'=>'URL Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'Url','data'=>'%2Fblocked.html','function'=>'Contains']))));
- Rule by User Agent
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions on a specific User Agent.
The Blocked User Agent String used in this example was User Agent String HereUserAgentBlock={"name": "User Agent Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "UserAgent","data":"User Agent String Here","function":"Contains"}])}
$UserAgentBlock = array('name'=>'User Agent Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'UserAgent','data'=>'User Agent String Here','function'=>'Contains']))));
- Rule by Header
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions by Header.
The name of the Blocked header in this example was HeaderName and the value of the header was HeaderValue
HeaderBlock={"name": "Header Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "Header","data":"HeaderName=HeaderValue","function":"Contains"}])}
$HeaderBlock = array('name'=>'Header Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'Header','data'=>'HeaderName=HeaderValue','function'=>'Contains']))));
- Rule by HTTP Method
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions by HTTP Method.
The valid options for the HTTP Method are POST, GET, HEAD, PUT, DELETE, PATCH and OPTIONS
MethodBlock={"name": "Method Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "HttpMethod","data":"post"}])}
$MethodBlock = array('name'=>'Method Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'HttpMethod','data'=>'post']))));
- Rule by File Extension
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions by File Extension.
The Blocked extension used in this example was FileExtension
FileExtBlock={"name": "File Extension Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "FileExt","data":"FileExtension"}])}
$FileExtBlock = array('name'=>'File Extension Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'FileExt','data'=>'FileExtension']))));
- Rule by Content Type
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions by Content Type.
The example Blocked content type used here was text/html
ContentTypeBlock={"name": "Content Type Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "MimeType","data":"text/html"}])}
$ContentTypeBlock = array('name'=>'Content Type Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'MimeType','data'=>'text/html']))));
- Rule by Country
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions by Country.
The example country code Blocked in this example was US . You can use multiple by separating them with a comma ( , ).
CountryBlock={"name": "Country Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "Country","data":"US"}])}
$CountryBlock = array('name'=>'Country Block','action'=>'Block','active'=>'1','conditions'=>json_encode(array((['scope'=>'Country','data'=>'US']))));
- Rule by Organization
This rule allows the use of Allow, Block, Captcha, Browser Validation, Extended Browser or Monitor actions by Organization.
The example Organization string Blocked in this case was Organization Name
OrgBlock={"name": "Organization Block","action": "Block","active": "1","conditions": json.dumps([{"scope": "Organization","data":"Organization Name"}])}
$OrgBlock = array('name'=>'Organization Block','action'=>'Monitor','active'=>'1','conditions'=>json_encode(array((['scope'=>'Organization','data'=>'Organization Name']))));