I would like to build a javascript widget that third party developers inject on their page by adding:

<script type="text/javascript" src="https://test.com/widget.js" async></script>

The script injects the email collection form widget into a div tag on the developer website. When a user submits the form, it makes a POST request to an endpoint hosted on our server. We use recaptcha to validate all requests.

There are some security implicatons:

  • Bad actor can spam the endpoint with bad email addresses.
  • Since the widget is embedded on the developer page, they can use the widget for nefarious purposes and have our name on it.

How can I address the security issues that comes with an embeddable widget? All requests go through HTTPS. Recaptcha is used to help against spam/abuse. Maybe I can use a site key/referrer header to validate that the request is coming from a trusted website?

Another option is to use an iframe hosted on my website to show the widget.

  • 1
    You can't trust referrers or any headers that come from the client as the client can spoof them. Commented Mar 28, 2018 at 20:26
  • IMO, the two security implications applies even if you don't embed this widget: so long the endpoint exists, it might be abused (no matter the "shape" of the client: python, cli, widget you made, etc) and since it's targeted for somewhere else on the internet (ie not your own domain), then attacker don't need the widget to put your name on anything bad
    – Xenos
    Commented Aug 21, 2019 at 13:39

2 Answers 2


The fact that you are embedding this as a widget is not all that relevant for most security aspects. Most attacks would be directed right at the endpoint, bypassing the form, widget and browser alltogether. For instance, you would need the captcha no matter if you make a widget or not, because spam is sent with automated scripts and not done through browsers.

You can, however, limit what origins can send requests to your endpoints from a browser. This would be done using CORS, only allowing some origins in your Access-Control-Allow-Origin header.

The trick to make this work is that the request must not be "simple", i.e. it must trigger a preflight. An ordinary form POST is simple, so that will not do it. You would have to change the verb, or require a specific header to be present in the request or something like that. See the link above for what is considered "simple" and what is not.

Do note, however, that it is the browser that enforces CORS policy. An attacker can still send whatever requests they want using e.g. CURL. Also note that even if you do not make a widget, anyone can just create a form that posts to your endpoint on their own webpage.


There are multiple measures you can take:

  1. Block bad bots and reduce traffic to you server like https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker

  2. As Anders said use CORS to whitelist client's domains so the script won't be abused on random websites.

  3. Server side always escape all strings and validate emails format. Further more anyone can attack you server direct not only thought "frontend" widget.

Notice: Relaying on http headers isn't secure as they can be easily spoofed by any reverse proxy to you script.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .