One day at CodePen, we woke up to a ton of customer support tickets about their Pens being broken, which ultimately boiled down to a version of Chrome that shipped where they ripped out
prompt() and I-don’t-know-what-else (
.htpasswd protected assets?).
Cross-origin iframes are essentially the heart of how CodePen works. You write code, and we execute it for you in an iframe that doesn’t share the same domain as CodePen itself, as the very first line of security defense. We didn’t hear any heads up or anything, but I’m sure the plans were on display.
There are all sorts of security and UX-annoyance issues that can come from iframes though. That’s why sandboxing is a thing. I can do this:
<iframe sandbox="allow-scripts allow-downloads ...etc"></iframe>
Daaaaaang. Entirely? That’s the word. Imagine the number of programming tutorials that will just be outright broken.
For now, even the cross-origin removal is delayed until January 2022, but as far as we know this is going to proceed, and then subsequent steps will happen to remove them entirely. This is spearheaded by Chrome, but the status reports that both Firefox and Safari are on board with the change. Plus, this is a specced change, so I guess we can waggle our fingers literally everywhere here, if you, like me, feel like this wasn’t particularly well-handled.
What we’ve been told so far, the solution is to use
postMessage if you really absolutely need to keep this functionality for cross-origin iframes. That sends the string the user uses in
window.alert up to the parent page and triggers the alert from there. I’m not the biggest fan here, because:
- I have to inject code into users code for this. This is new technical debt and it can harm the expectations of expected user output (e.g. an extra
<script>in their HTML has weird implications, like changing what
:nth-childand friends select).
- I’m generally concerned about passing anything user-generated to a parent to execute. I’m sure there are theoretical ways to do it safely, but XSS attack vectors are always surprising in their ingenouity.
Even lower-key suggestions, like
window.alert = console.log, have essentially the same issues.
Allow me to hand the mic over to others for their opinions.
Couldn’t the alert be contained to the iframe instead of showing up in the parent window?
Jaden Baptista, Twitter
Yes, please! Doesn’t that solve a big part of this? While making the UX of these dialogs more useful? Put the dang dialogs inside the
“Don’t break the web.” to “Don’t break 90% of the web.” and now “Don’t break the web whose content we agree with.”
Matthew Phillips, Twitter
I respect the desire to get rid of inelegant parts [of the HTML spec] that can be seen as historical mistakes and that cause implementation complexity, but I can’t shake the feeling that the existing use cases are treated with very little respect or curiosity.
Dan Abramov, Twitter
I always thought there was a sort of “prime directive” not to break the web? I’ve literally seen web-based games that used
alertas a “pause”, leveraging the blocking nature as a feature. Like:
<button onclick="alert('paused')">Pause</button>[.] Funny, but true.
Ben Lesh, Twitter
A metric was cited that only 0.006% of all page views contain a cross-origin iframe that uses these functions, yet:
Seems like a misleading metric for something like
confirm(). E.g. if account deletion flow is using
confirm()and breaks because of a change to it, this doesn’t mean account deletion flow wasn’t important. It just means people don’t hit it on every session.
Dan Abramov, Twitter
That’s what’s extra concerning to me:
alert() is one thing, but
confirm() literally returns
false, meaning it is a logical control structure in a program. Removing that breaks websites, no question. Chris Ferdinandi showed me this little obscure website that uses it:
Speaking of Chris:
The condescending “did you actually read it, it’s so clear” refrain is patronizing AF. It’s the equivalent of “just” or “simply” in developer documentation.
I read it. I didn’t understand it. That’s why I asked someone whose literal job is communicating with developers about changes Chrome makes to the platform.
This is not isolated to one developer at Chrome. The entire message thread where this change was surfaced is filled with folks begging Chrome not to move forward with this proposal because it will break all-the-things.
Chris Ferdinandi, “Google vs. the web”
And here’s Jeremy:
[…] breaking changes don’t happen often on the web. They are—and should be—rare. If that were to change, the web would suffer massively in terms of predictability.
Secondly, the onus is not on web developers to keep track of older features in danger of being deprecated. That’s on the browser makers. I sincerely hope we’re not expected to consult a site called
Jeremy Keith, “Foundations”
I’ve painted a pretty bleak picture here. To be fair, there were some tweets with the Yes!! Finally!! vibe, but they didn’t feel like critical assessments to me as much as random Google cheerleading.
Believe it or not, I generally am a fan of Google and think they do a good job of pushing the web forward. I also think it’s appropriate to waggle fingers when I see problems and request they do better. “Better” here means way more developer and user outreach to spell out the situation, way more conversation about the potential implications and transition ideas, and way more openness to bending the course ahead.