☁️ Cloudflare Web Application Firewall Rules
By using these WAF expressions, you can effectively block most unnecessary and potentially malicious requests targeting your origin server, thereby enhancing its security.
No Pro account or higher plan is required - everything works fine on the free Cloudflare plan.
If you find this repository useful, I would greatly appreciate it if you could give it a star ⭐. Thank you!
🛑 SniffCat and AbuseIPDB integrations
The script supports two external services that provide dynamic lists of known malicious IP addresses: SniffCat and AbuseIPDB.
When you set SNIFFCAT_API_TOKEN and/or ABUSEIPDB_API_KEY, the script fetches IP addresses from the APIs on every sync and merges them with the static rules/ip-blocklist.txt before uploading to Cloudflare Lists.
This significantly extends the IP blocklist without any manual effort. Both integrations work independently of each other - you can enable one, both, or neither.
Cloudflare allows up to 10,000 entries per list. Each integration can be configured via two optional environment variables:
SniffCat:
SNIFFCAT_CONFIDENCE_MIN - minimum confidence level (0-100) required to include an IP address. Default: 80.
SNIFFCAT_LIMIT - maximum number of IP addresses fetched per sync. Default: 3000.
AbuseIPDB:
ABUSEIPDB_CONFIDENCE_MIN - minimum confidence score (0-100) required to include an IP address. Default: 75.
ABUSEIPDB_LIMIT - maximum number of IP addresses fetched per sync. Default: 3000. Cloudflare allows up to 10,000 entries per list.
Without SNIFFCAT_API_TOKEN and ABUSEIPDB_API_KEY, both integrations are skipped and only the static list is used.
🛡️ What Can This List Block?
| Part (1-5) |
Description |
Action |
| 🔥 Part 1 - Suspicious paths & headers |
Blocks data leaks, suspicious referrers, malicious and unusual URL paths, as well as empty or anomalous User-Agents. |
Block |
| 🧨 Part 2 - Malicious extensions & injections |
Blocks suspicious requests, exploits, path traversal, configuration file access attempts, and the use of CLI tools in URLs. |
Block |
| 🤖 Part 3 - Unwanted bots |
Blocks unnecessary, harmful bots, scanners, and web scrapers. |
Block |
| 🦕 Part 4 - Ancient browsers & IP blocklist |
Blocks traffic from the Tor network, known malicious IP addresses, ASNs linked to botnets, and very outdated browsers. |
Block |
| 🗑️ Part 5 - Deprecated browsers & CMS |
Enforces additional verification for outdated browsers (Chrome 73-122, Firefox 62-118), old OS versions, and CMS scanners. |
Managed Challenge |
✅ Usage
Automatic (highly recommended)
You can use the JavaScript code from this repository to automatically update the rules throughout the day.
There’s no need to add them manually, as the script takes care of everything for you. 😉
Requirements
- Node.js LTS + npm
- PM2 (
npm i pm2 -g)
- Git
- Linux (also works on Windows Server)
Tutorial (for Linux)
- Clone this repository:
git clone https://github.com/sefinek/Cloudflare-WAF-Expressions.git cf-expressions
- Install the necessary dependencies:
cd cf-expressions && npm install
- Copy the
.env.example file and rename it to .env:cp .env.example .env
- Open the
.env file and configure the following variables:
- Paste your Account API token (Account → Manage account → Account API tokens) in place of
CF_API_TOKEN. The token needs the following permissions:

Rules are deployed as WAF custom rules via the Rulesets API. The legacy Firewall Rules API was deprecated on 15.06.2025 and no longer accepts modifications. An old token may stop working if you use User API Tokens. Migrating to Account API tokens is highly recommended.
- Set
CF_ACCOUNT_ID to your Cloudflare Account ID (32 characters, found in the URL: dash.cloudflare.com/<account_id>/configurations/lists) - required for IP list synchronization
- Set
CF_IP_BLOCKLIST_NAME to a custom name for the managed IP list, leave the default (sefinek_cf_waf), or leave it empty to disable IP list synchronization entirely

- Set
PHP_SUPPORT to true if your website uses PHP (removes the Managed Challenge rule for .php files)
- Set
WORDPRESS_SUPPORT to true if your website runs WordPress (removes the Managed Challenge rules for /wp-admin, /wp-content and /wp-includes paths so the admin panel, themes, plugins, CSS and images load correctly; also set PHP_SUPPORT=true)
- To enable PHP or WordPress only for selected domains, leave the flags at
false and list the zones in PHP_SUPPORT_ZONES / WORDPRESS_SUPPORT_ZONES (comma-separated, e.g. example.com,example.org). A zone gets the support if the global flag is true or the zone is on the list
- Set
SNIFFCAT_API_TOKEN to include dynamic malicious IPs from SniffCat (optional, but highly recommended)
- Set
ABUSEIPDB_API_KEY to include dynamic malicious IPs from AbuseIPDB (optional, but highly recommended)
nano .env
- Run the script 24/7 using PM2:
pm2 start && pm2 save
- Configure PM2 to start on system boot:
eval "$(pm2 startup | grep sudo)"
Manually
This method is not recommended. WAF expressions and IP blocklists should be kept up to date at all times to remain effective against new threats. Updating them manually is error-prone and easy to forget. Use the automatic method instead.
- Log in to your Cloudflare account.
- Select the domain where you want to add the expressions.
- Click on the
Security tab, then choose WAF from the dropdown menu.
- In the
Custom rules tab, click the Create rule button.
- Copy the expressions from the rules/expressions.md file.
- Click
Edit expression and paste the copied expressions.
- Click
Deploy to save the changes. Repeat this process for the remaining parts of the expressions, ensuring you select the appropriate action (Block or Managed Challenge) as specified in the file.
- Done! The expressions are now active and will start blocking unwanted traffic to your origin server. Make sure your website functions correctly, and visit this repository periodically for the latest updates.
IP Blocklist (Part 4)
Part 4 references a Cloudflare Custom IP List (ip.src in $sefinek_cf_waf). To set it up manually:
- Go to your Cloudflare dashboard and navigate to Manage account > Configurations > Lists.
- Click Create list, set the Identifier to
sefinek_cf_waf (cannot be changed later), and confirm.
- Open the newly created list, add the IP addresses from
rules/ip-blocklist.txt, and save.
- Part 4 will now block all IPs from that list.
On the free Cloudflare plan, you can have only 1 custom IP list per account (up to 10,000 entries). Paid plans allow more. Remember to update it regularly as new entries are added to rules/ip-blocklist.txt. The automatic method handles this for you.
📥 How to Update
The rules (rules/expressions.md and rules/ip-blocklist.txt) are downloaded automatically before every sync from api.sefinek.net (with GitHub as a fallback), so new rules reach you without updating the script. The API only publishes rule files that passed validation, and it always serves the newest rules in the format your version of the script understands. Each downloaded file is validated first: if it is broken or requires a newer version of the script, the last valid copy is kept and you get a warning.
The script itself is not updated automatically. When a new version is available, you will see a notification in the logs (and via email/Discord, if configured). To update, navigate to the project directory and run:
npm run update
To remove all WAF custom rules and the IP blocklist from Cloudflare (e.g. before a fresh install), run:
node data/tools/deleteWAFRules.js
The script will list everything it found and ask for confirmation before deleting anything. It also clears the local rule ID cache (data/rule-ids.json).
This operation is irreversible! All custom WAF rules and the managed IP list will be permanently deleted from your Cloudflare account.
🤝 Pull requests
If you have any suggestions or improvements, feel free to open a Pull request.
Your contribution will be appreciated and will help keep this list up-to-date and effective in combating the latest threats. Thank you!
🔖 GNU GPL v3 License
Copyright © 2023-2026 Sefinek
评论