How Submissions Are Protected

Last update: September 2, 2026
•
1 min to read

Overview

HubstreamFORMS is a public, anonymous surface, so every submission runs a gauntlet of checks before anything reaches your Hubstream instance. The person filling out the form sees only one of them — the security check widget above the Submit button. The rest are invisible.

The trust model in one line: the browser is untrusted and never sees your Hubstream server or API keys — it only knows the form’s opaque public ID. All credentials stay server-side in application settings.

The layers

Checks run cheapest-first; a submission must pass all of them:

  1. Size cap. Oversized requests are rejected before they’re even parsed.
  2. Rate limits. Per-visitor and per-form submission limits absorb volume abuse. Over-limit visitors get a “try again later” response.
  3. Invisible bot trap (honeypot). Each form session includes a hidden field with a rotating, unguessable name. Humans never see it; a bot that fills it gets a fake success — its submission is silently dropped and it learns nothing. Bots that skip the page and post to the API directly fail because they can’t know the current field name.
  4. CAPTCHA (Cloudflare Turnstile). The widget above the Submit button. The token it issues is verified with Cloudflare on every submission and is single-use — a captured request can’t be replayed. If Cloudflare can’t be reached, submissions fail closed rather than slipping through.
  5. Upload gating. Forms with image or PDF fields don’t accept a single byte of file data until the bot trap and CAPTCHA have passed. Uploads are further limited per visitor, capped at 15 MB per file, and restricted to the allowed image/PDF types.

What to configure for production

The protections have development fallbacks that keep the site working but offer no real protection — a form published with test keys shows a security widget labeled “testing only” that always passes. Before go-live, set real values in the Static Web App’s application settings:

SettingValue
TURNSTILE_SITE_KEYPublic widget key from the Cloudflare dashboard
TURNSTILE_SECRET_KEYThe matching secret key
EMBED_HONEYPOT_SECRETAny long random string

Turnstile needs only a free Cloudflare account — no plan, no DNS changes; the only Cloudflare touchpoints are the widget and the verification call.

If the form is embedded in other websites: every hostname that iframes the form must be added to the Turnstile widget’s allowed hostnames in the Cloudflare dashboard, or the security check refuses to load on that site.

Limits at a glance

Defaults, adjustable via application settings:

LimitDefault
Submissions per visitor10 per 10 minutes
Submissions per form100 per 10 minutes
Form loads per visitor30 per 5 minutes
File uploads per visitor20 per 10 minutes
File size15 MB per file

If a legitimate campaign expects heavier traffic (a public appeal, a deadline rush), raise the per-form limit ahead of time.

What this doesn’t cover

These controls stop scripted spam and naive bots. A determined attacker using paid CAPTCHA-solving services and a large pool of IP addresses is a different tier of threat — countering that requires a web application firewall with bot management in front of the site. Talk to Hubstream if your form is likely to attract that level of attention.