I think you just need to examine your cost/benefits and use cases. Any time you’re working with something like widgets, you’re always going to have security concerns. The way I think about some of our use cases:
- Pulling publicly available data from our db (e.g., a feed of articles from our site)
- Pushing data to our db (e.g., a newsletter signup form)
- Accomplishing user-authenticated actions (e.g., displaying content to a user signed in via a widget)
In example 1, we are only pulling information from our app, and that information is already publicly available, so the security issues here are minimal.
In example 2, we are pulling and pushing to our app, so we have increased security issues here. We use a schema to ensure that we are only working with strings, and we match our widget origin with the header data to ensure that we are seeing widget data from the website that was intended. We also use a honeypot and some other internal measures to help weed out bots.
In example 3, we are into user auth via a widget, and to me, this is where you need an iframe. I’d probably spin up a microservice with whatever functionality I’m looking to accomplish here, as bundling a client-facing app and serving it into an iframe probably isn’t going to be a good experience.
tl;dr: There are inherent security concerns to serving up code on someone else’s site. Cost/benefit determines how you mitigate those concerns.