Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/waf/patterns.md
1# Common Patterns23## Deploy Managed Rulesets45```typescript6// Deploy Cloudflare Managed Ruleset (default)7await client.rulesets.create({8zone_id: 'zone_id',9kind: 'zone',10phase: 'http_request_firewall_managed',11name: 'Cloudflare Managed Ruleset',12rules: [{13action: 'execute',14action_parameters: {15id: 'efb7b8c949ac4650a09736fc376e9aee', // Cloudflare Managed16// Or: '4814384a9e5d4991b9815dcfc25d2f1f' for OWASP CRS17// Or: 'c2e184081120413c86c3ab7e14069605' for Exposed Credentials18},19expression: 'true', // All requests20// Or: 'http.request.uri.path starts_with "/api"' for specific paths21enabled: true,22}],23});24```2526## Override Managed Ruleset2728```typescript29await client.rulesets.create({30zone_id: 'zone_id',31phase: 'http_request_firewall_managed',32rules: [{33action: 'execute',34action_parameters: {35id: 'efb7b8c949ac4650a09736fc376e9aee',36overrides: {37// Override specific rules38rules: [39{ id: '5de7edfa648c4d6891dc3e7f84534ffa', action: 'log' },40{ id: '75a0060762034b9dad4e883afc121b4c', enabled: false },41],42// Override categories: wordpress, sqli, xss, rce, etc.43categories: [44{ category: 'wordpress', enabled: false },45{ category: 'sqli', action: 'log' },46],47},48},49expression: 'true',50}],51});52```5354## Custom Rules5556```typescript57await client.rulesets.create({58zone_id: 'zone_id',59kind: 'zone',60phase: 'http_request_firewall_custom',61name: 'Custom WAF Rules',62rules: [63// Attack score-based64{ action: 'block', expression: 'cf.waf.score gt 50', enabled: true },65{ action: 'challenge', expression: 'cf.waf.score gt 20', enabled: true },6667// Specific attack types68{ action: 'block', expression: 'cf.waf.score.sqli gt 30 or cf.waf.score.xss gt 30', enabled: true },6970// Geographic blocking71{ action: 'block', expression: 'ip.geoip.country in {"CN" "RU"}', enabled: true },72],73});74```7576## Rate Limiting7778```typescript79await client.rulesets.create({80zone_id: 'zone_id',81kind: 'zone',82phase: 'http_ratelimit',83name: 'Rate Limits',84rules: [85// Per-IP global limit86{87action: 'block',88expression: 'true',89action_parameters: {90ratelimit: {91characteristics: ['cf.colo.id', 'ip.src'],92period: 60,93requests_per_period: 100,94mitigation_timeout: 600,95},96},97},9899// Login endpoint (stricter)100{101action: 'block',102expression: 'http.request.uri.path eq "/api/login"',103action_parameters: {104ratelimit: {105characteristics: ['ip.src'],106period: 60,107requests_per_period: 5,108mitigation_timeout: 600,109},110},111},112113// API writes only (using counting_expression)114{115action: 'block',116expression: 'http.request.uri.path starts_with "/api"',117action_parameters: {118ratelimit: {119characteristics: ['cf.colo.id', 'ip.src'],120period: 60,121requests_per_period: 50,122counting_expression: 'http.request.method ne "GET"',123},124},125},126],127});128```129130## Skip Rules131132```typescript133await client.rulesets.create({134zone_id: 'zone_id',135kind: 'zone',136phase: 'http_request_firewall_custom',137name: 'Skip Rules',138rules: [139// Skip static assets (current ruleset only)140{141action: 'skip',142action_parameters: { ruleset: 'current' },143expression: 'http.request.uri.path matches "\\.(jpg|css|js|woff2?)$"',144},145146// Skip all WAF phases for trusted IPs147{148action: 'skip',149action_parameters: {150phases: ['http_request_firewall_managed', 'http_ratelimit'],151},152expression: 'ip.src in {192.0.2.0/24}',153},154],155});156```157158## Complete Setup Example159160Combine all three phases for comprehensive protection:161162```typescript163const client = new Cloudflare({ apiToken: process.env.CF_API_TOKEN });164const zoneId = process.env.ZONE_ID;165166// 1. Custom rules (execute first)167await client.rulesets.create({168zone_id: zoneId,169phase: 'http_request_firewall_custom',170rules: [171{ action: 'skip', action_parameters: { phases: ['http_request_firewall_managed', 'http_ratelimit'] }, expression: 'ip.src in {192.0.2.0/24}' },172{ action: 'block', expression: 'cf.waf.score gt 50' },173{ action: 'managed_challenge', expression: 'cf.waf.score gt 20' },174],175});176177// 2. Managed ruleset (execute second)178await client.rulesets.create({179zone_id: zoneId,180phase: 'http_request_firewall_managed',181rules: [{182action: 'execute',183action_parameters: { id: 'efb7b8c949ac4650a09736fc376e9aee', overrides: { categories: [{ category: 'wordpress', enabled: false }] } },184expression: 'true',185}],186});187188// 3. Rate limiting (execute third)189await client.rulesets.create({190zone_id: zoneId,191phase: 'http_ratelimit',192rules: [193{ action: 'block', expression: 'true', action_parameters: { ratelimit: { characteristics: ['cf.colo.id', 'ip.src'], period: 60, requests_per_period: 100, mitigation_timeout: 600 } } },194{ action: 'block', expression: 'http.request.uri.path eq "/api/login"', action_parameters: { ratelimit: { characteristics: ['ip.src'], period: 60, requests_per_period: 5, mitigation_timeout: 600 } } },195],196});197```