Platform
WAF, bot protection and static egress IP
OWASP CRS firewall (Coraza), custom rules, sign-in bot protection with automatic bans and a dedicated static egress IP.
Security -> WAF puts a web application firewall in front of your project's API gateway, based on Coraza and the OWASP Core Rule Set (Apache-2.0). REST, Auth, GraphQL, Functions and Realtime traffic is checked for SQL injection, XSS, path traversal, RCE and scanners before it reaches your database.
Modes and paranoia level
| Mode | Behaviour |
|---|---|
off | CRS rules disabled (custom rules and bot protection can still run) |
detect | Logs events only - the request goes through. Start here to spot false positives |
block | A request over the anomaly threshold gets HTTP 403 (WAF_BLOCKED) |
Paranoia level 1-4 (default 1) enables more rules at the price of more false positives. The anomaly threshold (default 5) is the rule score sum at which a request is blocked. Request bodies are inspected up to 128 KB; Storage (/storage/v1/) skips body inspection so uploads stay fast.
Rule exclusions
When a rule gives a false positive (e.g. a text field containing SQL-like words), add an exclusion: a path prefix plus CRS rule ids (900000-999999), e.g. /rest/v1/todos -> 942350. Find the rule id in the WAF events.
Custom rules
- allowed IPs/CIDRs (bypass the whole firewall) and blocked IPs/CIDRs,
- country block or allow list (ISO-2) - geolocation: IP Geolocation by DB-IP (DB-IP Lite, CC-BY 4.0),
- User-Agent blocking (substring or
/regex/), empty UA and well-known scanners (sqlmap, nikto, nmap...), - maximum request size (HTTP 413).
Events and charts
The events tab shows the rule id, message, redacted matched data (e-mail addresses, long tokens and numbers are masked; Authorization/Cookie headers are never stored), client IP, country, path and action (blocked / detected / limited / banned). Charts show requests, blocked, detected, rate-limited and banned counts plus the top rules, IPs and paths. A sudden attack spike raises an "Attack detected on the project API" notification.
Bot protection (sign-in)
/auth/v1/token, /otp, /verify and /recover get an adaptive per-IP rate limit (default 30/min for sign-in, 10/min for OTP) that shrinks as an IP accumulates failures. After N failed attempts (default 10 within 10 minutes) the address gets an automatic ban on the Auth endpoints (default 15 min; repeat offenders double up to 24 h). Remove a ban with Unban in the dashboard, or via the API, CLI or MCP; you can also ban an address manually (a manual ban blocks the whole API).
CAPTCHA: configure Cloudflare Turnstile / hCaptcha keys in Auth -> Attack protection (GOTRUE_SECURITY_CAPTCHA_*); the WAF page shows whether it is on. It requires a captcha token on sign-in and sign-up.
Static egress IP
By default outbound traffic of your Edge Functions, pg_net in the database and Workers leaves from the server's shared address. Enabling Security -> Static IP pins it to a dedicated public address you can add to partners' allowlists. The address is shown in the dashboard. Test it from a worker:
curl -s https://ifconfig.me/ip # returns the address shown in the dashboard
It covers components running on the project's database host (not the dedicated workers host).
Pricing
- OWASP CRS firewall (detect or block): 39 PLN net / month per project, Pro plan or higher.
- Static egress IP: 15 PLN net / month per project (Pro+), billed hourly.
- Bot protection, IP/country/User-Agent rules and size limits are included in every plan.
Limitations
/workers/v1/...routes and Sites are not behind the firewall.- If the WAF proxy fails, the API stays up: traffic falls back directly to the project gateway (fail-open).
- Responses are not inspected - the WAF protects inbound traffic.
API, MCP and CLI
curl -X PUT https://host.ulewicz.space/api/v1/projects/<ref>/security/waf \
-H "Authorization: Bearer $HOSTBASE_TOKEN" -H "Content-Type: application/json" \
-d '{"mode":"block","paranoia":1,"bot":{"enabled":true},"rules":{"block_countries":["RU"]}}'
GET /api/v1/projects/<ref>/security/waf/events?limit=100&kind=crs
GET /api/v1/projects/<ref>/security/waf/stats?hours=24
GET|POST /api/v1/projects/<ref>/security/waf/bans DELETE .../bans/<ip>
GET|PUT /api/v1/projects/<ref>/security/egress { "enabled": true }
MCP: get_waf, set_waf, list_waf_events, get_waf_stats, list_waf_bans, ban_ip, unban_ip, get_static_egress, set_static_egress.
hostbase waf set --mode detect --bot on
hostbase waf set --mode block --paranoia 2 --exclude /rest/v1/todos=942350 --block-country RU
hostbase waf events --kind crs --limit 50
hostbase waf bans list
hostbase waf bans unban 203.0.113.7
hostbase egress enable