Security: URL bar spoof with wrong host badssl
Reported by
chromium...@gmail.com,
Apr 2 2016
|
|||||||||
Issue descriptionVERSION Chrome Version:51.0.2696.0 canary Operating System: windows 7 REPRODUCTION CASE 1. Open the testcase. 2. The testcase will open a new tab "google.com" and after 2 seconds the page will load to "wrong.host.badssl.com". 3. Switch the testcase and click on "Click here" button then back to the target page. 4. Observe.
,
Apr 3 2016
Issue 599951 has been merged into this issue.
,
Apr 3 2016
Hello, could one of you help confirm if this is a bug or not (and assign if so). Many thanks.
,
Apr 3 2016
,
Apr 3 2016
This doesn't seem to work for me. The testcase tries and fails to open a popup window, clicking the link in the popup blocker opens a tab to Google, pressing the button in the testcase does nothing. IIUC, this is basically complaining that the address bar state does not update when showing an interstitial? If so that doesn't seem like an exploitable security issue.
,
Apr 3 2016
Well, you can repro this bug easily with this testcase. Press on the button and wait 3 seconds, the address bar will update to google.com.
,
Apr 4 2016
Doesn't seem to repro for me on 51.0.2693.2, Win 10 x64. My address bar shows ianfette.org.
,
Apr 4 2016
I can half-reproduce. (Note: you need to enable popups from the testcase window.) The interstitial page will show "google.com" for a second but then go back to showing the correct URL for a second. I'm guessing there is some issue with how the virtual URL is updated when x.location changes.
,
Apr 4 2016
I can repro using the steps in comment 6 in 51.0.2695.1 and 51.0.2699.0 (no need to enable popups). Agreed that it doesn't repro in 51.0.2693.2. Probably a recent regression. This looks like a bug where we're discarding the pending entry without discarding the interstitial. It's ugly and we should fix it, but I don't see much of a security implication. Seems like you'd just be able to make the user think a victim site was untrustworthy, since the attacker doesn't have control over the content of the interstitial. I'm familiar with this logic, but I don't have a lot of time today. Nasko, would you be able to take a look?
,
Apr 4 2016
Yes, I'll take a look.
,
Apr 5 2016
,
Apr 5 2016
Nasko confirmed this is due to https://codereview.chromium.org/1683593002. I'm reverting until we can track down how it's happening.
,
Apr 5 2016
Reverted in r385235. We should confirm that this fixes the spoof in tomorrow's canary.
,
Apr 6 2016
Unfortunately, the revert didn't help. It bisected very well to that revision and local revert didn't repro anymore, but today's canary (51.0.2701.0) still reproduces the issue. It is a race condition and the CL we reverted probably increased the probability of it happening, but wasn't the root cause.
,
Apr 6 2016
Is this a security vulnerability? What's the attack scenario? Can wrong.host.badssl.com script google.com, for example?
,
Apr 6 2016
Dumping my current understanding of what is happening with the repro. The window.open step is basically to allow JS to control the navigations. Being renderer initiated, they are not going to swap processes by default. The first navigation to google.com is establishing a session history entry for googlg.com and a successful commit. The second navigation is to a page that causes an interstitial page to show up. What I'm observing is that the navigation starts, but we don't reach RenderFrameImpl::didFailProvisionalLoad. The interstitial page is correctly loaded in a different process and displayed. The timeout value for the second navigation should be big enough for all the steps above to complete. The second navigation is what tickles enough state in the renderer to get to RenderFrameImpl::didFailProvisionalLoad for the first navigation, then hit RenderFrameImpl::didStartProvisionalLoad for the second navigation. It is then again stuck and makes no forward progress. At this stage we update the omnibox and it shows an incorrect URL. I haven't traced why that is the case, but my hypothesis is that these navigations being renderer-initiated (therefore not as trusted), we end up falling back and displaying the last committed URL (google.com in the repro). Here is a short log of some logging I've put in to help diagnose (tests.netsekure.org being google.com and wrong.host.badssl.com causing the interstitial): // New window navigated to localhost, which serves the repro page [67396:67396:0406/142932:ERROR:render_frame_host_impl.cc(217)] RFH[0x61800012cc80]::RFH: routing_id:4 instance:2:http://localhost/ [67432:67432:0406/142932:ERROR:render_frame_impl.cc(1033)] RF[0x61900005af80]::RF: routing_id:4 [67432:67432:0406/142932:ERROR:render_frame_impl.cc(2998)] RF[0x61900005af80]::didStartProvisionalLoad: url:http://tests.netsekure.org/ [67396:67396:0406/142932:ERROR:render_frame_host_impl.cc(908)] RFH[0x61800012cc80]::DidStartProvisionalLoad: url:http://tests.netsekure.org/ [67432:67432:0406/142932:ERROR:render_frame_impl.cc(3127)] RF[0x61900005af80]::didCommitProvisionalLoad: url:http://tests.netsekure.org/ [67396:67396:0406/142932:ERROR:render_frame_host_impl.cc(976)] RFH[0x61800012cc80]::DidCommitProvisionalLoad: url:http://tests.netsekure.org/ [67432:67432:0406/142932:ERROR:render_frame_impl.cc(3385)] RF[0x61900005af80]::didFinishDocumentLoad: url:http://tests.netsekure.org/ // First navigation to badssl starts here. [67432:67432:0406/142933:ERROR:render_frame_impl.cc(2998)] RF[0x61900005af80]::didStartProvisionalLoad: url:https://wrong.host.badssl.com/ [67396:67396:0406/142933:ERROR:render_frame_host_impl.cc(908)] RFH[0x61800012cc80]::DidStartProvisionalLoad: url:https://wrong.host.badssl.com/ [67396:67396:0406/142933:ERROR:render_frame_host_impl.cc(217)] RFH[0x61800012ac80]::RFH: routing_id:2 instance:3: // Not sure what is causing this LaunchProcess error or whether it matters. LaunchProcess: failed to execvp: // This is loading the interstitial page into the new renderer. [67396:67396:0406/142933:ERROR:render_frame_host_impl.cc(2037)] RFH[0x61800012ac80]::Navigate: url:data:text/html;charset=utf-8,%3C!doctype%20html%3E%0A%3Chtml%20i18n-values=%22dir%3Atextdirection;lang%3Alanguage%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset=%22utf-8%22%3E%0A%20%20%3Cmeta%20name=%22viewport%22%0A%20%20%20%20%20%20content=%22initial [67457:67457:0406/142934:ERROR:render_frame_impl.cc(1033)] RF[0x61900004f180]::RF: routing_id:2 [67457:67457:0406/142934:ERROR:render_frame_impl.cc(2998)] RF[0x61900004f180]::didStartProvisionalLoad: url:data:text/html;charset=utf-8,%3C!doctype%20html%3E%0A%3Chtml%20i18n-values=%22dir%3Atextdirection;lang%3Alanguage%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset=%22utf-8%22%3E%0A%20%20%3Cmeta%20name=%22viewport%22%0A%20%20%20%20%20%20content=%22initial [67396:67396:0406/142934:ERROR:render_frame_host_impl.cc(908)] RFH[0x61800012ac80]::DidStartProvisionalLoad: url:data:text/html;charset=utf-8,%3C!doctype%20html%3E%0A%3Chtml%20i18n-values=%22dir%3Atextdirection;lang%3Alanguage%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset=%22utf-8%22%3E%0A%20%20%3Cmeta%20name=%22viewport%22%0A%20%20%20%20%20%20content=%22initial [67457:67457:0406/142934:ERROR:render_frame_impl.cc(3127)] RF[0x61900004f180]::didCommitProvisionalLoad: url:data:text/html;charset=utf-8,%3C!doctype%20html%3E%0A%3Chtml%20i18n-values=%22dir%3Atextdirection;lang%3Alanguage%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset=%22utf-8%22%3E%0A%20%20%3Cmeta%20name=%22viewport%22%0A%20%20%20%20%20%20content=%22initial [67396:67396:0406/142934:ERROR:render_frame_host_impl.cc(976)] RFH[0x61800012ac80]::DidCommitProvisionalLoad: url:data:text/html;charset=utf-8,%3C!doctype%20html%3E%0A%3Chtml%20i18n-values=%22dir%3Atextdirection;lang%3Alanguage%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset=%22utf-8%22%3E%0A%20%20%3Cmeta%20name=%22viewport%22%0A%20%20%20%20%20%20content=%22initial [67457:67457:0406/142934:ERROR:render_frame_impl.cc(3385)] RF[0x61900004f180]::didFinishDocumentLoad: url:data:text/html;charset=utf-8,%3C!doctype%20html%3E%0A%3Chtml%20i18n-values=%22dir%3Atextdirection;lang%3Alanguage%22%3E%0A%3Chead%3E%0A%20%20%3Cmeta%20charset=%22utf-8%22%3E%0A%20%20%3Cmeta%20name=%22viewport%22%0A%20%20%20%20%20%20content=%22initial // Some time passes, the second navigation is kicking in here, causing the fail for the previous one and starting the second one. [67432:67432:0406/142937:ERROR:render_frame_impl.cc(3059)] RF[0x61900005af80]::didFailProvisionalLoad: url:https://wrong.host.badssl.com/ [67432:67432:0406/142937:ERROR:render_frame_impl.cc(2998)] RF[0x61900005af80]::didStartProvisionalLoad: url:https://wrong.host.badssl.com/ [67396:67396:0406/142937:ERROR:render_frame_host_impl.cc(920)] RFH[0x61800012cc80]::DidFailProvisionalLoadWithError: error:-3 [67396:67396:0406/142937:ERROR:web_contents_impl.cc(3726)] WC[0x61c0000af080]::LoadingStateChanged: ignoring due to interstitial [67396:67396:0406/142937:ERROR:web_contents_impl.cc(3726)] WC[0x61c0000af080]::LoadingStateChanged: ignoring due to interstitial // This IPC handler is causing the URL in the omnibox to be updated. [67396:67396:0406/142937:ERROR:render_frame_host_impl.cc(908)] RFH[0x61800012cc80]::DidStartProvisionalLoad: url:https://wrong.host.badssl.com/ In some cases, I've even hit this check (though rarely): [50048:50048:0406/141409:FATAL:ssl_error_handler.cc(159)] Check failed: !FromWebContents(web_contents). So my hypothesis is that we are having a bug somewhere in routing SSL or request/response information or it is being deferred when it is not expected. I will continue digging further and post updates as I find out more.
,
Apr 6 2016
A bit more information. I was able to repro a variation of this on Chrome Mac stable (49.0.2623.110). It still shows the committed page URL in the omnibox, but the spinner is spinning and the reload button is showing X. Clicking on it to stop the load leaves the URL in the omnibox and the interstitial page still showing for the not-committed site. A quick two iteration bisect shows that it is an old issue, as I was able to repro this behavior in build based on r318289 | |||||||||
Comment 1 by chromium...@gmail.com
, Apr 2 2016403 KB
403 KB Download