Security Model

Squeaker replaces image CAPTCHAs with proof-of-work verification. This document explains how challenges, tokens, and adaptive protection work.

Verification flow

  1. Challenge - Widget requests a signed challenge from GET /v1/challenge?sitekey=…&hostname=….
  2. Solve - Browser finds a valid nonce in an isolated Web Worker. Challenge parameters rotate daily so static bypass scripts stop working.
  3. Token - Solution is submitted to POST /v1/solve. API returns an HMAC-signed token (120s TTL).
  4. Verify - Your backend validates signature and expiry locally, then calls the API for replay protection.

Protection levels (1–5)

Each site has a protection level in the dashboard (default: 3 — Balanced). The level controls PoW difficulty, behavior sampling, and integrity requirements — not raw difficulty knobs.

LevelLabelTypical human solveWhat it does
1Light<1 secondMinimal PoW, rare behavior sampling
2Relaxed<1 secondLight PoW, occasional behavior checks
3Balanced~1 secondRecommended default — solid resistance, low friction
4Strict1–3 secondsAlways collects behavior; blocks automation signals
5Maximum2–5 secondsHardest PoW, mandatory behavior + integrity checks

When an IP's anomaly score rises, the API can temporarily bump difficulty above the site's base level. Scores decay over time so legitimate users are not permanently penalized.

Proof-of-work

The API sets difficulty from the site's protection level (and any adaptive bump). The widget solves the puzzle in a worker without blocking the page. Higher levels mean more CPU work for attackers scaling automated submissions. Exact solver details are not published and change over time.

Token format

Replay protection

Each token nonce is stored in Redis after successful remote verification. Submitting the same token twice returns replay. This prevents attackers from capturing and reusing tokens.

Behavior analysis

Depending on protection level and anomaly score, the widget may collect aggregated input patterns before solving:

Only summary metrics are sent — no raw coordinates, no persistent fingerprint. Levels 1–2 sample a fraction of sessions; levels 4–5 always require behavior data.

Integrity checks

At higher protection levels, the widget also sends an integrity summary with each solve:

Level 5 enforces the strictest thresholds. The API rejects solves that fail integrity scoring before issuing a token.

Rate limiting

Per-IP rate limits protect the challenge and solve endpoints. Excessive requests increase anomaly scores and trigger harder challenges or temporary blocks.

Domain whitelist

Each site key only works on domains configured in the dashboard. Requests from unlisted origins are rejected at the API level.

Key rotation

Rotate site keys from the dashboard at any time. Old tokens signed with the previous secret become invalid immediately after rotation. Update your server environment and redeploy.

Threat model

What Squeaker protects against

What requires additional measures

Best practices

  1. Always POST tokens to /v1/verify on your server before accepting form data.
  2. Start at level 3; raise to 4–5 only for high-value forms.
  3. Set strict domain whitelists per site.
  4. Rotate keys if a secret may have been exposed.
  5. Monitor /metrics for unusual solve failure rates.
  6. Review GDPR and data retention settings.