Security Settings

Configure checkout rate limiting and invisible CAPTCHA bot protection.

Overview

WooNooW provides targeted security controls to protect your checkout workflow from automated bot attacks, carding fraud, and order bombing.

Navigate to WooNooW → Settings → Security in your WordPress admin dashboard to configure rate limits and CAPTCHA credentials.


Checkout Rate Limiting

Rate limiting restricts the frequency of order submissions from an individual IP address. This mitigates automated checkout scripts, credential stuffing against coupons, and automated payment probing.

Settings are managed via WooNooW\Compat\SecuritySettingsProvider and stored in WordPress options:

SettingOption KeyDefaultDescription
Enable Checkout Rate Limitingwoonoow_enable_checkout_rate_limityesGlobal toggle to enable or disable IP-based checkout submission throttling.
Maximum Orderswoonoow_rate_limit_orders5Maximum number of orders allowed from an IP address within the sliding window (range: 1–100).
Time Window (minutes)woonoow_rate_limit_minutes10Duration of the sliding expiration window in minutes (range: 1–1440).

IP Detection Hierarchy

The rate limiter inspects request headers in the following priority order to identify client addresses behind proxies and CDNs:

  1. HTTP_CF_CONNECTING_IP (Cloudflare CDN)
  2. HTTP_X_FORWARDED_FOR (First IP in proxy chain)
  3. HTTP_X_REAL_IP (Reverse proxy / Nginx)
  4. REMOTE_ADDR (Direct TCP connection fallback)

Rate Limit Enforcement Lifecycle

  1. When a customer or bot sends POST /woonoow/v1/checkout/submit, the endpoint calls SecuritySettingsProvider::is_rate_limited().
  2. The system checks the transient woonoow_rate_{md5(ip)}.
  3. If existing attempts equal or exceed woonoow_rate_limit_orders, the request is rejected immediately with HTTP 200 and an error envelope:
    json
    {
      "error": "Too many orders. Please try again later."
    }
    
  4. If the order succeeds, SecuritySettingsProvider::record_order_attempt() increments the attempt count and refreshes the transient window TTL (rate_limit_minutes * 60). Failed validation attempts prior to order creation do not consume the quota.

Invisible CAPTCHA Protection

WooNooW supports invisible CAPTCHA verification to prevent automated bot submissions without adding interactive friction for legitimate customers.

Supported Providers

Configure the provider using the woonoow_captcha_provider option (none | recaptcha | turnstile).

Cloudflare Turnstile delivers privacy-preserving, invisible browser challenge verification without visual puzzles.

  • Site Key (woonoow_turnstile_site_key): Public site key provided by Cloudflare.
  • Secret Key (woonoow_turnstile_secret_key): Secret API key used for backend verification against https://challenges.cloudflare.com/turnstile/v0/siteverify.

Turnstile Verification & Replay Protection:

  • WooNooW computes sha256($token) and stores a temporary marker wnw_cft_{hash} in WordPress transients for 10 minutes (600 seconds).
  • Any attempt to submit the same token a second time is blocked with code captcha_duplicate.
  • Provider response codes are mapped directly to actionable API errors:
    • timeout-or-duplicate → captcha_expired or captcha_duplicate
    • missing-input-response → captcha_missing
    • invalid-input-response → captcha_invalid
    • missing-input-secret / invalid-input-secret → captcha_config

2. Google reCAPTCHA v3

Google reCAPTCHA v3 executes invisibly and calculates a risk score from 0.0 (likely bot) to 1.0 (likely human).

  • Site Key (woonoow_recaptcha_site_key): Public site key from Google reCAPTCHA console.
  • Secret Key (woonoow_recaptcha_secret_key): Secret API key used for server-side verification against https://www.google.com/recaptcha/api/siteverify.

reCAPTCHA Score Threshold:

  • WooNooW requires a minimum score of 0.5.
  • Scores below 0.5 are rejected with code captcha_score.
  • Tokens expire after 2 minutes; the WooNooW customer SPA automatically refreshes the token in the background on an interval.

Fail-Closed Security Policy

When a CAPTCHA provider is active (recaptcha or turnstile), verification operates on a strict fail-closed architecture:

  1. Mandatory Token: If captcha_token is omitted from the submission payload, checkout is rejected immediately (captcha_missing).
  2. Missing Configuration: If the provider secret key is blank or invalid, submissions fail closed with captcha_config.
  3. Network or Upstream Outages: If the verification HTTP request fails or times out (10s limit), the transaction is blocked (captcha_network_error).
  4. Single-Use Invalidation on Failure: On any order submission failure (such as card decline, expired coupon, or validation mismatch), the frontend immediately discards the active token and resets the CAPTCHA widget. Re-submitting requires a newly minted challenge token.

Public Bootstrap Exposure

Public frontend clients obtain security parameters without leaking secrets via GET /woonoow/v1/checkout/bootstrap.

The returned payload contains:

json
{
  "security": {
    "captcha_provider": "turnstile",
    "recaptcha_site_key": "",
    "turnstile_site_key": "0x4AAAAAA..."
  }
}

Secret keys (recaptcha_secret_key, turnstile_secret_key) are private to the PHP backend and never exposed in REST responses, HTML markup, or client bundles.


Last updated Sep 11, 2026