skip to Main Content

(Please put aside the utility/inadvisability of window.prompt usage – that’s not what this question is about. I’m using this case to debug a broader issue of frame-frame interference.)


I’m investigating how a cross-origin isolated child frame’s window.prompt is being "interrupted" (i.e. abruptly closed without user interaction) by some unknown code in a parent (or perhaps sibling) frame.

Things I know:

  • A frame can interrupt another cross-origin isolated frame’s prompt/alert/etc. by calling prompt/alert/etc. itself (regardless of parent/child relationship). The other frame’s prompt closes, and the new one appears in its place.
  • A parent frame can interrupt a cross-origin isolated child frame’s prompt/alert/etc. by navigating (i.e. window.location.reload(), window.location.href=...)
  • window.focus() does not interrupt another frame’s prompt/alert/etc.

This applies to Chrome Linux, Version 123.0.6312.105, at least. I’m not sure about other browsers. Unfortunately I’m not able to consistently reproduce instances of the "interruption" since I think the root cause is third-party ad code that is running in the parent frame, and it has only happened a couple of times over the course of a month.

I know that parent navigation and parent/sibling frame calls to prompt/alert/etc. are not the cause. The interruption happens without navigation or other prompts/alerts/popups/etc appearing. It just closes the iframe’s prompt, and that’s it.

An ideal answer to this question would simply give a list of tested/viable ways in which a cross-origin isolated parent or sibling frame could "interrupt" a frame’s prompt/alert/etc. – without causing a navigation or another prompt/popup/etc. to appear. There could be many causes, so the more possibilities listed, the better.

I suspect there could be behavioral differences between browsers on this issue, so answers that are only tested in Chrome are okay.

Thanks!

Addendum:

  • Per @Kaiido’s comment RE browser extensions potentially being a cause: It’s possible, but unlikely I think. I’ve only got DarkReader installed, and it was on the "off" state last time this happened. I’ve also received many user reports about problems that I’m quite sure are caused by this issue, including on Android Chrome. It tends to happen when the advert frame is loading/refreshing. Another effect (alongside the prompt closing effect) is that focus is stolen from any focussed textarea (which initially led me to believe this whole issue was caused by window.focus() in another frame). That said, I can’t know for sure that this is the same issue, but I can confirm that the prompt-closing effect tends to happen for me when the advert frame is loading/refreshing. I’m quite sure it’s the same underlying problem, but I don’t have a lot of data to go by.

2

Answers


  1. Chosen as BEST ANSWER

    One possible method might be to create a separate child frame, and trigger an alert (or prompt/confirm/etc.) within it, but then immediately destroy that iframe from the parent. The alert should "cancel" the one in the original child frame, but then be itself destroyed via the destruction of its own frame.

    That said, I don't think that's what is happening with my issue, because I don't see any other prompts appear even momentarily. The prompt in the cross-origin-isolated child frame seems to just "gracefully disappear" (without any user interaction).

    (Note that this, my own answer, doesn't qualify for my bounty, of course. Just posting this so others don't use something I've already thought of to claim the bounty.)


  2. Here’s my best attempt so far:

    The main frame loads an iframe and produces an alert. After one second, the iframe communicates next ad to the main frame and "asynchronously" (after 0 seconds) produces its own alert. This closes the alert of the main frame.
    The main frame receives the next ad communication and navigates the iframe. This closes the alert of the iframe.

    Since the iframe’s alert is produced and immediately closed again, you don’t notice it. The overall effect is just that the main frame’s alert is closed.

    main_frame.html

    <body onload="alert('alert')">
      <iframe id="a" src="http://other.domain/iframe.html"></iframe>
      <script type="text/javascript">
      onmessage = function() {
        a.src = "about:blank";
      };
      </script>
    </body>
    

    iframe.html

    <body onload="setTimeout(function() {
      parent.postMessage('next ad','*');
      setTimeout(() => alert(''));
    }, 1000)">
    </body>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search