SaFi Bank Space : Web Application Firewall - Security Architecture

(blue star) Overview

This document describes the implementation of WAF configuration in Cloudflare for SaFiBank. It highlights the design and principles for rulesets to be configured in Cloudflare.

This documentation do not contain specific procedures to create custom ruleset and configure manage ruleset in Cloudflare. Please refer to custom or manage ruleset documentations.

(blue star) Design

Proactive approach in hardening attack surface

Mitigation to critical vulnerabilities as first layer in the rulesets. It composes of Indicator-of-Compromise (IoC)'s, Exploit trigger’s, and Attack technique mitigations.

Second layer of the firewall are Anti-Money Laundering based rulesets. It is placed to manage traffic’s coming from blacklisted and grey listed countries tagged by Anti-Money Laundering Council (AMLC) such as FATF and Philippines AMLC.

Third layer is the OWASP Core Rulesets. This is a Cloudflare managed ruleset based from OWASP Top 10 vulnerabilities. It is updated regularly and maintained by ModSecurity.

Forth layer is the base Cloudflare Managed Ruleset. This ruleset is the base ruleset of the Cloudflare WAF solution and is enabled by default. It contains mitigations from threat landscape studied by Cloudflare security team.

(blue star) Implementation

(blue star) Vulnerability Ruleset

Server Side Request Forgery (SSRF) vulnerability characteristics

1. Check the URI of the request if containing HTTP or FTP redirections.

lower(http.request.uri) matches \"(http|https|ftp)?://[^\s]+\"

2. OR check the IP and domain reputation of the source. Refer to Cloudflare documentation for threat score values.

cf.threat_score > 0

3. Combine the detection mechanisms as final expression.

lower(http.request.uri) matches \"(http|https|ftp)?://[^\s]+\" or cf.threat_score > 0

4. Set the action to block the request.

action: "block"

Final custom rule should look like:

{
  "expression":"(lower(http.request.uri) matches \"(http|https|ftp)?://[^\s]+\") or cf.threat_score > 0",
  "action": "block",
  "description": "Block SSRF HTTP/FTP redirections or bad IP/domain reputation"
}

Log4shell Indicator of Compromise via User-Agent Header detection

  1. Check the URI of the request if containing JNDI LDAP requests.

lower(http.user_agent) matches \"(jndi)?:(ldap)?://[^\s]+\"

2. OR check the IP and domain reputation of the source. Refer to

Cloudflare documentation for threat score values.

cf.threat_score > 0

3. Combine the detection mechanisms as final expression.

lower(http.user_agent) matches \"(jndi)?:(ldap)?://[^\s]+\" or cf.threat_score > 0

4. Set the action to block the request.

action: "block"

Final custom rule should look like:

{
  "expression":"(lower(http.user_agent) matches \"(jndi)?:(ldap)?://[^\s]+\") or cf.threat_score > 0",
  "action": "block",
  "description": "Block Log4shell JNDI exploit via User-Agent Header or based on IP Reputation"
}

Log4shell Indicator of Compromise via Request URI detection

1. Check the Request URI of the request if containing JNDI LDAP requests.

lower(http.request.uri) matches \"(jndi)?:(ldap)?://[^\s]+\"

2. OR check the IP and domain reputation of the source. Refer to

Cloudflare documentation for threat score values.

cf.threat_score > 0

3. Combine the detection mechanisms as final expression.

lower(http.request.uri) matches \"(jndi)?:(ldap)?://[^\s]+\" or cf.threat_score > 0

4. Set the action to block the request.

action: "block"

Final custom rule should look like:

{
  "expression":"(lower(http.request.uri) matches \"(jndi)?:(ldap)?://[^\s]+\") or cf.threat_score > 0",
  "action": "block",
  "description": "Block Log4shell JNDI exploit via Request URI or based on IP Reputation"
}

(blue star) SaFi AML Ruleset

Block Democratic People's Republic of Korea (DPRK)

1. Check IP Geolocation.

ip.geoip.country eq \"KP\"

2. Set the action to block the request.

action: "block"

Final custom rule should look like:

{
  "expression":"ip.geoip.country eq \"KP\"",
  "action": "block",
  "description": "Block traffic coming from IP based on DPRK"
}

Block Islamic Republic of Iran

1. Check IP Geolocation.

ip.geoip.country eq \"IR\"

2. Set the action to block the request.

action: "block"

Final custom rule should look like:

{
  "expression":"ip.geoip.country eq \"IR\"",
  "action": "block",
  "description": "Block traffic coming from IP based on Iran"
}

Challenge all AML Gray listed countries with Medium security level

1. Check IP Geolocation that match to Gray listed countries.

ip.geoip.country eq \"AL\" or

2. Set the action to challenge the request.

action: "challenge"

Final custom rule should be look like:

{
  "expression":"ip.geoip.country eq \"AL\"",
  "action": "challenge",
  "description": "Challenge traffic coming from IP based on Iran with medium security level"
}

3. Repeat for remaining Gray listed countries except Philippines (PH).

  • Barbados (BB)

  • Burkina Faso (BF)

  • Cambodia (KH)

  • Cayman Islands (KY)

  • Democratic Republic of Congo (CD)

  • Gibraltar (GI)

  • Haiti (HT)

  • Jamaica (JM)

  • Jordan (JO)

  • Mali (ML)

  • Morocco (MA)

  • Mozambique (MZ)

  • Panama (PA)

  • Senegal (SN)

  • South Sudan (SS)

  • Syrian Arab Republic, Syria (SY)

  • United Republic of Tanzania (TZ)

  • Türkiye (TR)

  • Uganda (UG)

  • United Arab Emirates (AE)

  • Yemen (YE)

OWASP Core Ruleset

Enable OWASP Core Ruleset following the steps described here: https://developers.cloudflare.com/waf/managed-rulesets/reference/owasp-core-ruleset/

Cloudflare Managed Ruleset

Enable Cloudflare Managed Ruleset following the steps described here: https://developers.cloudflare.com/waf/managed-rulesets/reference/cloudflare-managed-ruleset/

Attachments: