Protect Arcadia Application with Declarative WAF¶
Warning
ONLY IF YOU START THE LAB FROM HERE - ELSE DON’T READ THIS WARNING. If you want to start from here (because you are only interested by Declarative WAF), and do not want to run all the steps before, you can use Postman
and Jenkins
to create everything for you. To do so, follow the steps below.
Open
Jenkins
and run the pipelineDeployMainApp
Open
Postman
, and select the collectionArcadia Manual Pipeline - no CICD
Run the calls
Login to NGINX Controller
Create WebApp Application
Create MainApp Component
Create BackEnd Component
Open
Jenkins
and run the pipelineDeployApp2
Open
Postman
, and select the collectionArcadia Manual Pipeline - no CICD
Run the call
Create App2 Component
Open
Jenkins
and run the pipelineDeployApp3
Now, Arcadia App is fully deployed and the NGINX Controller is set up.
In this module, we will deploy a WAF policy to protect Arcadia Bank application and we will publish it. With v16.0 (and in draft in v15.1), the WAF policy can be deployed via a declarative call, and the WAF policy itself is a JSON file.
Note
We use the new v15.1/v16.0 Declarative WAF policy. You can retrieve the JSON Policy in the GitLab repo and below.
Note
You can learn more on the Declarative WAF policy here : https://f5.sharepoint.com/sites/EMEASystemsEngineering/SitePages/Adv.-WAF-v16.0-Declarative-API.aspx
{
"policy": {
"name": "policy-fund-1",
"description": "Policy Example - Rapid Deployment",
"template": {
"name": "POLICY_TEMPLATE_RAPID_DEPLOYMENT"
},
"enforcementMode": "blocking",
"server-technologies": [
{
"serverTechnologyName": "MySQL"
},
{
"serverTechnologyName": "Unix/Linux"
},
{
"serverTechnologyName": "MongoDB"
}
],
"signature-settings": {
"signatureStaging": false
},
"policy-builder": {
"learnOnlyFromNonBotTraffic": false
},
"response-pages": [
{
"responsePageType": "ajax",
"ajaxEnabled": true,
"ajaxPopupMessage": "My customized popup message! Your support ID is: <%TS.request.ID()%>"
}
]
}
}
Note
You can notice this JSON policy is based in Rapid Deployment template and we added few things like Server-Technologies, Signature Staging, Policy Buidler and Response Page.
Step 1 - Send an attack¶
In
Chrome
, in Arcadia web application, refer a friendRefer bob@sponge.com
Send an attack with the below payload in the
refer friend
field{\"$ne\":\"michael@gmail.com\"}
Note
This attacks means return everything not equals to
michael@gmail.com
Attack succeed and you can get the DB content
Step 2 - Push AS3 declaration to deploy the WAF policy¶
Note
It is important to understand what we are doing here. We are leveraging all the new v16.0 Adv. WAF Declarative policy features. With one API call (done by Jenkins and Ansible), we will deploy a new AS3 declaration with a WAF policy.
Check the files used here¶
In
Gitlab
, openAdministrator / as3-waf
projectYou can see several files, but the most important are
playbook-v16.yaml
as3-v16.json
policy-fund-1.json
Open
policy-fund-1.json
{ "policy": { "name": "policy-fund-1", "description": "Policy Example - Rapid Deployment", "template": { "name": "POLICY_TEMPLATE_RAPID_DEPLOYMENT" }, "enforcementMode": "blocking", "server-technologies": [ { "serverTechnologyName": "MySQL" }, { "serverTechnologyName": "Unix/Linux" }, { "serverTechnologyName": "MongoDB" } ], "signature-settings": { "signatureStaging": false }, "policy-builder": { "learnOnlyFromNonBotTraffic": false }, "response-pages": [ { "responsePageType": "ajax", "ajaxEnabled": true, "ajaxPopupMessage": "My customized popup message! Your support ID is: <%TS.request.ID()%>" } ] } }
Note
This is our declarative JSON WAF policy
Open
as3-v16.json
{ "class": "AS3", "action": "deploy", "persist": true, "declaration": { "class": "ADC", "schemaVersion": "3.2.0", "id": "Prod_Web_AS3", "Web-Prod": { "class": "Tenant", "defaultRouteDomain": 0, "arcadia": { "class": "Application", "template": "generic", "VS_WebApp": { "class": "Service_HTTPS", "remark": "Accepts HTTPS/TLS connections on port 443", "virtualAddresses": ["10.1.10.26"], "redirect80": false, "pool": "pool_NGINX_WebApp", "policyWAF": { "use": "Arcadia_WAF_policy" }, "securityLogProfiles": [{ "bigip": "/Common/Log all requests" }], "profileTCP": { "egress": "wan", "ingress": { "use": "TCP_Profile" } }, "profileHTTP": { "use": "custom_http_profile" }, "serverTLS": { "bigip": "/Common/arcadia_client_ssl" } }, "Arcadia_WAF_policy": { "class": "WAF_Policy", "url": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-fund-1.json", "ignoreChanges": true }, "pool_NGINX_WebApp": { "class": "Pool", "monitors": ["http"], "members": [{ "servicePort": 8080, "serverAddresses": ["10.1.20.10"] }] }, "custom_http_profile": { "class": "HTTP_Profile", "xForwardedFor": true }, "TCP_Profile": { "class": "TCP_Profile", "idleTimeout": 60 } } } } }
Note
In this AS3 declaration, you can notice the new v16.0 Adv. WAF Reference section (
Arcadia_WAF_policy
). This section refers to our external JSON policy file, and will upload, import and apply the policy in the BIG-IP.Open
playbook-v16.yaml`
--- - hosts: bigip connection: local gather_facts: false vars: my_admin: "admin" my_password: "admin" bigip: "10.1.1.12" tasks: - name: Deploy AS3 WebApp uri: url: "https://{{ bigip }}/mgmt/shared/appsvcs/declare" method: POST headers: "Content-Type": "application/json" "Authorization": "Basic YWRtaW46YWRtaW4=" body: "{{ lookup('file','as3-v16.json') }}" body_format: json validate_certs: no status_code: 200
Note
You can see the playbook is very simple in v16.0 thanks to the AS3 call. It will do all the job for us. This playbook is just sending an AS3 declaration call to the BIGIP.
Run the CI/CD pipeline¶
In
Jenkins
, click onDeployWAF
pipelineRun the
pipeline
In
Chrome
, launch an incognito window, and retry the attack{\"$ne\":\"michael@gmail.com\"}
Attack fails and you can notice the
AJAX blocking page
set in the JSON declarative WAF policyCheck logs in the BIG-IP