As I write, this is the attribute soup on an <iframe>
on CodePen in order to dial in the right combination of security and usability:
<iframe
sandbox="allow-downloads allow-forms allow-modals allow-pointer-lock allow-popups allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation"
allow="accelerometer; camera; encrypted-media; display-capture; geolocation; gyroscope; microphone; midi; clipboard-read; clipboard-write; web-share"
allowpaymentrequest="true"
allowfullscreen="true">
</iframe>
Wow! I think that’s an awful lot of detailed HTML to get right. If any little bit of that was wrong, we’d hear about it here at CodePen right away. It would break what users expect to work.
To compound this issue, the above code is just the output for Chrome-n-friends. Both Safari and Firefox need variations of this HTML to be perfect. That puts us in UA-sniffing territory, which is never a particularly happy place.
Add extra attributes or values to this code, you might make annoying extra console noise — quite annoying in an app for developers. Skip them, and you cripple the app itself. We have no choice but to render user code in an <iframe>
, for all the obvious cross-origin security it provides.
Compounding things again, all this code changes. New features arrive in browsers that require new iframe permissions. But there is no good place to follow all the changes, so the way we tend to find out is when a user graciously sends in a support request for something that doesn’t work that they think should.
The code itself is just… strange! Why is sandbox
space-separated but allow
is semicolon-separated (some context)? Why are sandbox
and allow
different attributes at all? Especially when they are both whitelists? Why are some features their own special attributes?
Just feels like an awful lot of weirdness for one isolated purpose.
I was just looking over our setup here at CodePen and refactoring it a bit, and decided to chuck the attributes in JSON to maintain from there, so here’s a copy of that in case it’s useful to anyone else.