Front-end security
Three layers of protection for anonymous form submissions and public record access.
Layer 1: Honeypot
A hidden field (pfm_hp) is added to every form. Real browsers leave it empty because it's not visible. Bots that auto-fill all fields get caught. Filled honeypot = 422 rejection.
Layer 2: Per-IP rate limiting
Anonymous submissions are rate-limited per IP address. Default: 30 submissions per IP per hour. Stored as WordPress transients keyed by pfm_arl_{sha1(entity|ip)}.
// Customise rate limit
add_filter('pfm_anonymous_default_rate_limit', fn() => 10); // 10 per hour
// Block all anonymous access
add_filter('pfm_anonymous_rate_limit', fn() => 0);
Layer 3: CAPTCHA
The pfm/captcha/verify filter lets you integrate Cloudflare Turnstile, hCaptcha, or any other CAPTCHA service. The plugin does not ship with a CAPTCHA implementation — you bring your own.
All three layers are bypassed for logged-in users (they already authenticate via WordPress nonces).
Additional protections
- Nonce verification on all state-changing REST endpoints
- Optimistic locking (
sys_version) prevents concurrent edit conflicts - Field-level write checks — each touched field is individually verified
- Row visibility rules filter records at the SQL level, not just the UI