Cloudflare Security
Security best practices and configuration for WAF, Zero Trust, Tunnel, rate limiting, and DDoS protection.
WAF (Web Application Firewall)
Managed Rulesets
Enable OWASP protection:
# Via API
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id}/rulesets/phases/http_request_firewall_managed/entrypoint" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{
"rules": [{
"action": "execute",
"expression": "true",
"action_parameters": {
"id": "efb7b8c949ac4650a09736fc376e9aee",
"version": "latest"
}
}]
}'
Custom WAF Rules
Block SQL Injection:
(http.request.uri.query contains "SELECT" and http.request.uri.query contains "FROM") or (http.request.uri.query contains "UNION" and http.request.uri.query contains "SELECT")
Block XSS:
http.request.uri.query contains "<script" or http.request.uri.query contains "javascript:" or http.request.body.raw contains "<script"
Rate Limit Auth Endpoints:
(http.request.uri.path contains "/auth/login" and rate(http.request.ip, 5) > 10)
Common WAF Patterns
// Pattern 1: Block by country
(ip.geoip.country in {"CN" "RU"})
// Pattern 2: Challenge suspicious User-Agents
(http.user_agent contains "bot" or http.user_agent contains "crawler")
// Pattern 3: Protect upload endpoints
(http.request.uri.path eq "/api/upload" and http.request.method eq "POST")
// Pattern 4: Hotlink protection
(http.request.uri.path matches "\\.(jpg|jpeg|png|gif)$" and
not http.referer contains "your-domain.com")
Zero Trust
Setup with Identity Provider
Clerk OIDC Integration:
{
"name": "Clerk",
"type": "oidc",
"config": {
"client_id": "your-clerk-client-id",
"client_secret": "your-clerk-secret",
"auth_url": "https://your-domain.clerk.accounts.dev/oauth/authorize",
"token_url": "https://your-domain.clerk.accounts.dev/oauth/token",
"certs_url": "https://your-domain.clerk.accounts.dev/.well-known/jwks.json"
}
}
Access Policies
Admin Dashboard Protection:
{
"name": "Admin Dashboard",
"application_domain": "admin.your-domain.com",
"policies": [{
"name": "Allow Admins Only",
"decision": "allow",
"include": [{
"email": ["admin@your-domain.com"]
}],
"require": [{
"email_domain": ["your-domain.com"]
}]
}]
}
API Access Control:
{
"name": "API Access",
"policies": [{
"name": "Require Authentication",
"decision": "allow",
"include": [{
"everyone": true
}],
"require": [{
"auth_method": "identity_provider"
}]
}]
}
Cloudflare Tunnel
Setup
# Install cloudflared
# Windows: Download from cloudflare.com
# Mac: brew install cloudflare/cloudflare/cloudflared
# Linux: Download deb/rpm
# Login
cloudflared tunnel login
# Create tunnel
cloudflared tunnel create my-tunnel
# Configure tunnel
cat > ~/.cloudflared/config.yml <<EOF
tunnel: my-tunnel-id
credentials-file: /path/to/credentials.json
ingress:
- hostname: app.example.com
service: http://localhost:3000
- hostname: api.example.com
service: http://localhost:8080
- service: http_status:404
EOF
# Route DNS
cloudflared tunnel route dns my-tunnel app.example.com
# Run tunnel
cloudflared tunnel run my-tunnel
As a Service (Production)
# Install as service cloudflared service install # Start service cloudflared service start
Rate Limiting
In Workers
export default {
async fetch(request, env) {
const ip = request.headers.get('CF-Connecting-IP');
const key = `ratelimit:${ip}`;
// Get current count
const count = parseInt(await env.KV.get(key) || '0');
// Check limit
if (count >= 100) {
return new Response('Rate limit exceeded', {
status: 429,
headers: { 'Retry-After': '60' }
});
}
// Increment
await env.KV.put(key, (count + 1).toString(), {
expirationTtl: 60 // 1 minute window
});
return handleRequest(request, env);
}
};
Via Dashboard Rules
Create rate limiting rule:
- •Characteristics: IP Address
- •Period: 60 seconds
- •Requests: 100
- •Action: Block
- •Duration: 60 seconds
DDoS Protection
Automatic Protection
Cloudflare automatically protects against:
- •Layer 3/4 DDoS (network/transport)
- •Layer 7 DDoS (application)
- •Volumetric attacks
Under Attack Mode
Enable when under attack:
# Via API
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/security_level" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{"value":"under_attack"}'
Effect: Shows 5-second JavaScript challenge before allowing access
Disable after attack subsides:
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/security_level" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{"value":"medium"}'
Bot Management
Challenge Bad Bots
(cf.bot_management.score lt 30)
Actions:
- •Block: Deny access completely
- •Challenge: Show CAPTCHA
- •JS Challenge: Require JavaScript execution
- •Log: Allow but log for analysis
Verified Bots
Allow good bots (Google, Bing):
(cf.bot_management.verified_bot eq true)
API Shield
mTLS (Mutual TLS)
Require client certificates:
- •Upload client CA certificate to Cloudflare
- •Create mTLS rule:
code
(http.request.uri.path contains "/api/")
- •Action: Require valid client certificate
Schema Validation
Define API schema (OpenAPI/Swagger):
paths:
/api/users:
post:
parameters:
- name: email
required: true
schema:
type: string
format: email
Enable validation: Blocks requests that don't match schema
Security Headers
In Workers
const securityHeaders = {
'Content-Security-Policy': "default-src 'self'",
'X-Frame-Options': 'DENY',
'X-Content-Type-Options': 'nosniff',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'Permissions-Policy': 'geolocation=(), microphone=(), camera=()',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload'
};
export default {
async fetch(request, env) {
const response = await handleRequest(request, env);
// Add security headers
Object.entries(securityHeaders).forEach(([key, value]) => {
response.headers.set(key, value);
});
return response;
}
};
Best Practices for BlockDrive
WAF Configuration
Location: /cloudflare/waf-rules.json
Key rules:
- •Block SQL injection
- •Block XSS attempts
- •Rate limit auth endpoints (10 req/min)
- •Rate limit upload endpoints (50 req/min)
- •Challenge suspicious user agents
- •Hotlink protection for files
Zero Trust Policies
Location: /cloudflare/zero-trust-policies.json
Policies:
- •Admin dashboard: Clerk OIDC authentication
- •API access: Valid JWT tokens
- •Premium features: Paid users only
API Gateway Worker
Location: /workers/api-gateway/
Security features:
- •Rate limiting per IP
- •CORS validation
- •Security headers
- •Request logging
- •Input sanitization
Security Incident Response
Step 1: Assess
# Check security events # Dashboard → Security → Events # View blocked requests # Look for patterns: IPs, paths, methods
Step 2: Immediate Mitigation
# Enable Under Attack Mode
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/security_level" \
-d '{"value":"under_attack"}'
# Or block specific IPs
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/firewall/access_rules/rules" \
-d '{
"mode": "block",
"configuration": {
"target": "ip",
"value": "malicious.ip.address"
}
}'
Step 3: Create Targeted Rules
For credential stuffing:
(http.request.uri.path eq "/auth/login" and rate(http.request.ip, 5) > 5)
For scraping:
(http.request.uri.query contains "page=" and rate(http.request.ip, 10) > 50)
Step 4: Monitor
- •Watch Analytics → Security
- •Set up notifications for high block rates
- •Review Logpush exports for patterns
Troubleshooting
Legitimate traffic blocked: Check Security → Events, identify false positives, add exception rules
Rate limiting too aggressive: Increase thresholds or add exceptions for trusted IPs
Zero Trust login failing: Verify IdP configuration, check callback URLs, test IdP independently
Tunnel not connecting: Check credentials file path, verify network connectivity, check cloudflared logs
For cost optimization of security features, see cloudflare-cost-optimization skill.