New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 771719 link

Starred by 5 users

Issue metadata

Status: Duplicate
Merged: issue 500260
Owner:
Closed: Oct 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 2
Type: Bug



Sign in to add a comment

When navigating back, iFrames created on load frequently have their innerHTML replaced with contents of different iFrames on the page

Reported by ricky.bl...@oath.com, Oct 4 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

Steps to reproduce the problem:
Isolated to as simple a test case as we can:
1. Start chrome in mixed content mode (only to replace remote script with a locally served isolated copy): `open /Applications/Google\ Chrome.app --args --allow-running-insecure-content`

2. Use a local http server to serve this file, call it adsWrapperMock.js:
```
if (document.readyState && document.readyState === 'complete') {
  adsTacFn();
} else {
  document.addEventListener('DOMContentLoaded', adsTacFn, false);
}

function adsTacFn() {
  var container = document.getElementById('fi_ad_leaderboard');

  var testIframe = document.createElement('iframe');
  testIframe.id = 'myAboutBlankIframe';
  testIframe.src = 'about:blank';
  testIframe.style.width = '950px';
  testIframe.style.height = '250px';
  testIframe.style.border = '1px solid red';

  container.appendChild(testIframe);
}

// Stubs for calls made by aol.com
function adsDisableFileless() {}
function adSetAdURL() {}
function adSetOthAT() {}
function adSetMOAT() {}
```

3. In Chrome, use Switcheroo to switch "https://s.aolcdn.com/ads/adsWrapper.js" to the above locally served file, e.g. http://localhost:8080/adsWrapperMock.js

4. Browse to http://aol.com and observe the red 970x250 iframe created by the locally served file at the top.

5. Click any content link on the page that stays within the same tab.

6. Click the Chrome back button.

7. Inspect the contents of the 970x250 red iframe created by the locally served file. Does it stay as about:blank? Repeat steps 5-7 up to 10 times or so until that about:blank iframe is filled with the contents of another random iframe on the page. Might have a visual presence, might have to Inspect Element to see DOM in the iframe.

This is a very simple base case, but still on a full website because the large page size seems to have something to do with it.

Or, to get the issue to happen much more frequently, disable the standalone test file in Switcheroo, browse to this URL and follow steps 5 to 7 above: https://www.aol.com/?atwCrPr=https://ibw.aol.com/IBW/creativePreview/1038012/index;970;250;0

What is the expected behavior?
When navigating back, the innerHTML of iFrames created on page load should contain only their own innerHTML and not be crossed with the contents of another iframe that exists on the page.

What went wrong?
The iframe innerHTML gets filled with the contents of another iframe on the page, yet its src attribute does not change. For example see the attached screenshots to see how the NPR player iframe innerHTML has filled our empty about:blank frame, but it's a random selection not just NPR.

Did this work before? N/A 

Does this work in other browsers? Yes

Chrome version: 61.0.3163.100  Channel: stable
OS Version: OS X 10.12.6
Flash Version: 

This is not specific to aol.com - happens also on msn.com and techcrunch.com.
 
standalone test - about-blank frame innerHTML became NPR player .png
788 KB View Download
standalone test - about-blank frame innerHTML became NPR player - inspect element.png
638 KB View Download
full on ad rendering test - iframe contents are from another iframe not from the URL in the src attribute.png
382 KB View Download
Components: Blink>HTML>IFrame
Labels: Needs-Triage-M61
This appears to be similar to this 2015 ticket that is still open: https://bugs.chromium.org/p/chromium/issues/detail?id=500260

In that ticket, someone suggested there that this issue applies to unnamed iFrames. We just tested adding a "name" attribute to an iFrame in addition to "id" that was already present, but its contents still got replaced with the contents of another iFrame when navigating back. See attached screenshot showing name attribute, and contents that are wrong.

Is there any known workaround until this can be fixed in Chrome? Thanks!
Screen Shot 2017-10-05 at 10.05.34 AM.png
280 KB View Download
In the comments of 500260 ojan@chromium.org posted over a year ago an awesomely simple repro, so copying it here so you don't need to follow the longer steps above.

1. Go to http://anforowicz.github.io/frame-creation-order/index.htm and observe red/green frames.
2. Close the tab.
3. Right click then "re-open closed tab".
4. Observe the contents of the red/green frames have switched.
Cc: hdodda@chromium.org
Labels: M-63 OS-Linux OS-Windows
Status: Untriaged (was: Unconfirmed)
Able to reproduce the issue on Mac os 10.12.6 , ubuntu 14.04 and windows 10 using chrome M61 #61.0.3163.100 and M63 #63.0.3235.0 as per steps mentioned in comment #3.

This issue is seen from M50 and is a non-regression issue.

Marking it as untraiged for further inputs on this.

Thanks!

Cc: lukasza@chromium.org creis@chromium.org
Components: -Blink>HTML>IFrame UI>Browser>History UI>Browser>Navigation
Labels: Needs-Feedback
This looks like a duplicate of  issue 500260 , but it is surprising that #c2 indicates that the issue doesn't go away after naming the frame.  FWIW, I cannot repro the issue when the frames are named - see http://anforowicz.github.io/frame-creation-order-with-named-frames/index.htm. 
 Maybe the name of the frame is set after the initial navigation in the frame (see  issue 607205  and RenderFrameImpl::DidChangeName method which skips updating the unique-name after the initial navigation).

ricky.blaha@, could you please clarify what you mean by "tested adding a "name" attribute to an iFrame" so that we can better understand your repro from #c2?
I had tried adding many variations of the simple test at http://anforowicz.github.io and yes as long as all frames had unique names it would work as expected, and when it was a mix between named and unnamed frames, only the unnamed frames were affected.

However when testing on aol.com those results did not carry over -- an async created named frame would still be replaced with the contents of an unnamed frames.

We have advised the site to name all frames, so they may make a change soon, but here are steps to repeat so you can at least see the issue I mentioned on Oct 5 happening:

1. Browse to https://www.aol.com/?atwCrPr=https://ibw.aol.com/IBW/creativePreview/1038012/index;970;250;0&atwUAC=adsWrapperName.js. This forces a 970x250 ad to appear at the top, and forces the fix of adding the "name" attribute to the async iFrame created for the results of the ad call.

2. See the 970x250 ad appear. Run this in the console to observe the iFrame containing the ad call has the "name" attribute: `document.querySelector('#atwAdFrame0')`. Expand the iframe in the console to see that the expected result is a div with an id of "adDiv" and some script tags that come from the ad call.

3. Click any content link then click back, and repeat a few times until you no longer see the 970x250 ad appear.

4. Once the 970x250 ad is missing, run this in the console to observe the iFrame containing still has the "name" attribute: `document.querySelector('#atwAdFrame0')`. Expand the iframe in the console to see that the contents have swapped with one of the other un-named iframes.

Run this in the console to see that there are currently 3 un-named iFrames on the page: `document.querySelectorAll('iframe:not([name])')`.

Hope that helps.
Labels: -Needs-Feedback
Owner: lukasza@chromium.org
Status: Assigned (was: Untriaged)
Thank you for the repro in #c6.  I tried looking closer and here are my notes:

One observation is that the atwAdFrame0 frame pointed out in step 2 in #c6:
1) has a name attribute (set to "atwAdFrame0")
2) doesn't have a contentWindow.name

    > var f = document.querySelector('#atwAdFrame0')
    ...
    > f.name
    "atwAdFrame0"
    > f.contentWindow.name
    ""
    > f.src
    ""
    > f.contentWindow.location.href
    "https://www.aol.com/?atwCrPr=https://ibw.aol.com/IBW/creativePreview/1038012/index;970;250;0&atwUAC=adsWrapperName.js"

In particular, it seems that we first create the frame with no name...

    FrameTree.cpp:66: SetName; pid = 71552; name = ""; this_frame_ = 0xa05ced3e388
    ...
    #2 0x7f58061a69a3 blink::FrameTree::SetName()
    #3 0x7f580594e570 blink::WebLocalFrameImpl::InitializeCoreFrame()
    #4 0x7f580594f763 blink::WebLocalFrameImpl::CreateChildFrame()
    #5 0x7f58057d3644 blink::LocalFrameClientImpl::CreateFrame()
    #6 0x7f58059f16ff blink::HTMLFrameOwnerElement::LoadOrRedirectSubframe()
    #7 0x7f58059eee24 blink::HTMLFrameElementBase::OpenURL()
    #8 0x7f58059ef904 blink::HTMLFrameElementBase::SetNameAndOpenURL()
    #9 0x7f58059efabe blink::HTMLFrameElementBase::DidNotifySubtreeInsertionsToDocument()
    #10 0x7f580546b1e0 blink::ContainerNode::DidInsertNodeVector()
    #11 0x7f580546bbb3 blink::ContainerNode::AppendChild()
    #12 0x7f5805575d6a blink::Node::appendChild()
    #13 0x7f58066b9376 blink::NodeV8Internal::appendChildMethodForMainWorld()
    #14 0x7f58066b9037 blink::V8Node::appendChildMethodCallbackForMainWorld()
    #15 0x7f58074bf2f2 v8::internal::FunctionCallbackArguments::Call()
    #16 0x7f58075ba953 v8::internal::(anonymous namespace)::HandleApiCallHelper<>()
    #17 0x7f58075b8b43 v8::internal::Builtin_Impl_HandleApiCall()
    #18 0x7f58075b850d v8::internal::Builtin_HandleApiCall()

... and only *later* set the frame's name *attribute*

    HTMLIFrameElement.cpp:126: ParseAttribute; pid = 71552; value = "atwAdFrame0"; ContentFrame() = 0xa05ced3e388
    ...
    #2 0x7f58059f6d7a blink::HTMLIFrameElement::ParseAttribute()
    #3 0x7f58054fda93 blink::Element::AttributeChanged()
    #4 0x7f58059dcbf7 blink::HTMLElement::AttributeChanged()
    #5 0x7f58055065c3 blink::Element::DidAddAttribute()
    #6 0x7f5805506505 blink::Element::AppendAttributeInternal()
    #7 0x7f58055103d6 blink::Element::SetAttributeInternal()
    #8 0x7f58054f8986 blink::Element::setAttribute()
    #9 0x7f5806939c31 blink::HTMLIFrameElementV8Internal::nameAttributeSetter()
    #10 0x7f5806939b06 blink::V8HTMLIFrameElement::nameAttributeSetterCallback()
    #11 0x7f58074bf2f2 v8::internal::FunctionCallbackArguments::Call()
    #12 0x7f58075ba953 v8::internal::(anonymous namespace)::HandleApiCallHelper<>()
    #13 0x7f58075b9204 v8::internal::Builtins::InvokeApiFunction()
    #14 0x7f5807b0700f v8::internal::Object::SetPropertyWithAccessor()
    #15 0x7f5807b1e53e v8::internal::Object::SetPropertyInternal()
    #16 0x7f5807b1e249 v8::internal::Object::SetProperty()
    #17 0x7f5807a13f94 v8::internal::StoreIC::Store()
    #18 0x7f5807a1ad10 v8::internal::__RT_impl_Runtime_StoreIC_Miss()

FWIW, HTML spec seems to say (https://html.spec.whatwg.org/#the-iframe-element):

    Whenever the name attribute is set, the nested browsing context's name must be changed
    to the new value. If the attribute is removed, the browsing context name must be set to
    the empty string.

OTOH, it seems to me that in https://crbug.com/632243 we are arguing that this propagation is not necessary and doesn't happen in other browsers.
Cc: foolip@chromium.org dcheng@chromium.org
+dcheng@ and foolip@ in case they want to add any comments wrt desirability of propagation of iframe.name changes into iframe.contentWindow.name.
Changing the iframe name once the subframe is created doesn't affect the browsing context name. This is a known bug and tracked in  issue 660485  =(
Mergedinto: 500260
Status: Duplicate (was: Assigned)
Thanks for the confirmation Daniel.  I guess as a workaround setting iframe.contentWindow.name should still work (at least for same-origin frames).

At any rate - the analysis above seems to show that this is indeed a duplicate of  issue 500260 .

Sign in to add a comment