Security

How to Restrict a Form Endpoint to Your Own Domain

Your form's action URL is sitting in plain view in your page source. Here's how to stop anyone else from posting to it.

· The SimpleForm Team

Open the page source of any site using a hosted form backend and the endpoint URL is right there in the action attribute. Anyone who copies it can post to it from a script, a curl command, or a copy of your form hosted on a completely different domain. Your inbox fills up, your dashboard fills up, and if you're close to your monthly submission cap, real customer messages start bouncing while you're still trying to figure out where the junk is coming from.

Domain restriction is a SimpleForm setting that ties a form's endpoint to an Allowed domains list. Any POST whose origin isn't on that list gets rejected with a 403 response before it is emailed, stored, or counted against your plan.

Why Does a Public Form Endpoint Get Abused?

Because nothing about an endpoint URL is secret once it ships. The action attribute is plain text in your HTML, visible to any bot that crawls the page, any competitor who views source, and any script kiddie testing random endpoints for open relays. Honeypot fields only catch bots that fill in every input blindly — a script written specifically against your form skips the hidden field entirely. IP rate limiting helps, but it allows up to 10 submissions per IP per endpoint per hour, so a slow trickle from a rotating set of IPs slides under that ceiling for days before anyone notices.

The most common version of this isn't a malicious hacker — it's a scraper building a list of live form endpoints to sell to a spam operation, or a site that copies your landing page wholesale, including the form markup, and never bothers to change the action attribute. Either way, the submissions that show up don't look like an attack at first. They look like a sudden run of low-quality leads with mismatched names and message bodies that read like ad copy, and by the time someone on the team notices the pattern, the free plan's 100-submission monthly cap can already be spent on noise instead of real inquiries.

What Does Domain Restriction Actually Block?

It checks the origin of the incoming request against the list of domains you've entered for that form, one per line, in the dashboard's form configuration. A match passes through to your normal pipeline — email, dashboard, webhook. Anything else gets a 403 Disallowed origin domain response and stops there. It is a separate layer from the other two defenses, not a replacement for either:

LayerStopsPlan
HoneypotBots that fill every field automaticallyAll plans
IP rate limitingBulk submissions from one addressAll plans, 10/hour
Domain restrictionSubmissions from any origin you didn't listPro and Agency
reCAPTCHA v3Automated browser-based submissionsPro and Agency, opt-in

Notice what's missing from the first two rows: neither one cares where the request came from. A honeypot only tests whether a field got filled in; rate limiting only counts requests per IP. Domain restriction is the only layer of the four that answers the question of whether this came from your own site

How Do You Turn On Domain Restriction?

You could build this yourself — stand up a small proxy or edge function that checks the Origin header before forwarding the request — but that means writing and maintaining code for a static site that was supposed to need none. SimpleForm's Allowed domains field does the same check as a form setting, with no code to deploy or patch. The docs cover every field in the form configuration screen, including this one, alongside redirect URLs and email recipients.

  1. Open the form's settings from your SimpleForm dashboard.
  2. Find the Allowed domains field in the form configuration section.
  3. Add each origin that should be allowed to submit, one per line — for example https://example.com and https://www.example.com as separate lines if you serve both.
  4. Save the form. New submissions are checked against the list immediately; nothing already delivered is affected.
  5. Submit a test entry from an allowed page to confirm it still goes through, then try posting from an unlisted origin to confirm it gets rejected.

What Happens to a Rejected Submission?

It never reaches your pipeline. The request gets a 403 response, nothing is emailed, nothing is written to your dashboard, no webhook fires, and it does not count against your monthly submission limit — that's a distinct code from the 402 you'd get for exceeding your plan's cap, and from the 429 you'd get for tripping the rate limiter. All three are deliberately different codes so you can tell, from your own client-side error handling, exactly which defense stopped a given request.

Will This Block My Own Staging or Preview Domains?

Only if you leave them off the list. This is the most common hesitation: teams run a form from production, a staging subdomain, and sometimes a preview URL from their host, and worry that locking down the endpoint will break the ones that aren't the production site. The Allowed domains field takes multiple lines, so add every legitimate origin — production domain, staging subdomain, and any preview host pattern you use regularly. The one thing it won't tolerate is an origin you never told it about, which is exactly the point.

If you're not sure a submission will match, the safest test is the same AJAX pattern described in the docs for JSON responses: submit with an Accept: application/json header and read the response code directly instead of guessing from a redirect.

Is Domain Restriction Worth Upgrading For?

It's a Pro and Agency feature, not part of the free plan — the plan comparison lists it alongside webhooks, auto-responder, and reCAPTCHA v3 as one of the differences between the two tiers. If your form only ever gets a handful of submissions a month and the free plan's 100-submission cap covers you comfortably, honeypot and rate limiting alone may be enough. Once an endpoint has been scraped and reused — which you'll usually notice as a spike of submissions with no matching referrer in your own analytics — domain restriction is the layer that actually stops it, rather than just slowing it down. Weigh it against the cost of the alternative: at $9 a month, Pro's domain restriction plus its 5,000-submission ceiling is cheaper than the hours it takes to triage a mailbox full of scraped junk by hand, or to explain to a client why their contact form's lead count doubled overnight for no real reason.

The check itself is a browser-security concept, not something SimpleForm invented: it mirrors how the CORS origin model works in browsers, applied here to a server-side allow list so it also covers requests that never go through a browser at all.

What Should You Check Before You Turn It On?

List every domain that legitimately submits the form, including any subdomain variants (with and without www) and any preview or staging host you test from regularly. Missing one means real submissions from that host start returning 403s, which looks identical to a broken form from the visitor's side — they see nothing, because your server never gets involved. Save your dashboard's Allowed domains field open in one tab and test from each real environment in another before you consider the change final.

Next Step

Create a free SimpleForm account, add your production domain as the form's action target, then upgrade to Pro from your dashboard when you're ready to turn on Allowed domains — the setting is on the same form configuration screen you already used to set your redirect URL and email recipients.

Frequently asked questions

A 403 means the submission's origin domain was not on that form's Allowed domains list, so SimpleForm rejected it before storing it, emailing it, or firing any webhook. It is a different code from the 402 returned for an exceeded submission limit and the 429 returned for rate limiting, so you can tell the defenses apart from your own error handling.

No. Domain restriction is included on the Pro and Agency plans alongside webhooks, auto-responder, and reCAPTCHA v3. The free plan relies on honeypot fields and IP rate limiting, which stop generic bots and bulk floods but do not check which site a submission actually came from.

Yes. The Allowed domains field accepts one origin per line, so you can list production, a www variant, a staging subdomain, and any preview host you use for testing. Every listed origin is checked the same way; anything not on the list is rejected.

No, it runs alongside them as a third layer. Honeypot fields catch bots that fill hidden inputs automatically, rate limiting caps submissions per IP per hour, and domain restriction checks the request's origin against your allow list. Each blocks a different kind of abuse, so all three stay active together.

Not if your site's domain is on the Allowed domains list. AJAX requests carry the same origin information as a normal form post, so a listed domain passes through whether the submission arrives as a redirect-based post or a fetch call with an Accept: application/json header.

Submit a test entry from a page on an allowed domain and confirm it arrives normally, then attempt a submission from any other origin — a local HTML file, a different domain, or a tool like curl with a spoofed Origin header — and confirm you get a 403 response instead of a delivered submission.

Ship a working form in five minutes. Point your form's action at a SimpleForm endpoint and submissions land in your inbox and dashboard straight away. Start free or read the docs.

More from the blog