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

Issue 839724 link

Starred by 2 users

Issue metadata

Status: Duplicate
Merged: issue 840176
Owner:
Closed: May 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Chrome , Mac
Pri: 2
Type: Bug
Team-Security-UX



Sign in to add a comment

XHR using HTTP Auth shows interstitial and does not hide it afterward

Reported by laurent....@acsone.eu, May 4 2018

Issue description

Chrome Version       : Version 66.0.3359.139 (Official Build) (64-bit)
URLs (if applicable) :
Other browsers tested:
  Add OK or FAIL, along with the version, after other browsers where you
have tested this issue:
     Safari:
    Firefox: OK
       Edge:

What steps will reproduce the problem?
In a JS script makes a CORS XHR request with 'withcredentials=true'
When the code is executed, the location/url of the current tab is changed to the url targeted by the XHR call.

What is the expected result?
An XHR request should never change the current location.


What happens instead?

Current location is replaced by the location of the XHR call.


 
IMO, the component into the issue is not the right one.... This functionality is disabled into my browser.

Comment 2 by creis@chromium.org, May 4 2018

Components: Blink>Network>XHR
Thanks-- we can remove the Site Isolation component if it's not specific to that.  Adding the XHR component to help get this triaged.

Can you post an example page with this problem, to help us repro it?  Or give a code snippet?
Here it's  an animated gif to illustrate the bug. When I click on a tab into the application an ajax request is done on an other site to get the documents to display (withcredentialls=True). Nevertheless, as of chrome 66 the ajax call changes the url from the current tab....
The application is not available outside our intranet. Therefore I can't provide a URL.

Here it's a sample page to reproduce the bug. You must change the url with a new one allowing CORS requests and protected by Basic auth.

<!DOCTYPE html>
<html>
<body>

<p>This example demonstrates that CORS request changes the URL of the current page.</p>

<button id="demo" onclick="myFunction()">Click me.</button>

<script>
function myFunction() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https:my-cors-enable-website.com', true);
    xhr.withCredentials = true;
    xhr.onload = function () {
      document.getElementById("demo").innerHTML = xhr.responseText;
    }
    xhr.send(null);
}
</script>

</body>
</html>


xhr-bug.gif
101 KB View Download

Comment 5 by creis@chromium.org, May 4 2018

Cc: mea...@chromium.org
Components: Internals>Network>Auth
Oh, the XHR is trying to use HTTP Auth.  Chrome intentionally blanks out the page during HTTP Auth and shows the URL you're authenticating to while the dialog is visible, so that users don't assume they're giving the password to the visible page (which could be an attacker's page).  That's usually for navigations that have HTTP Auth, but it applies to subresources and I suppose XHRs/fetches as well.

Pretty sure that's not Site Isolation related, but we can try to verify.

meacer@: Any thoughts on this XHR case?

Comment 6 by creis@chromium.org, May 4 2018

Cc: creis@chromium.org nasko@chromium.org est...@chromium.org
Components: -Internals>Sandbox>SiteIsolation UI>Security>UrlFormatting UI>Browser>Navigation UI>Browser>Interstitials
Labels: -Pri-3 OS-Chrome OS-Linux OS-Mac OS-Windows Pri-2
Owner: mea...@chromium.org
Status: Assigned (was: Unconfirmed)
Summary: XHR using HTTP Auth shows interstitial and does not hide it afterward (was: XHR using withCredentials = true change URL tab)
Actually, there is a problem here.  I just tested this with a test-only HTTP Auth URL.  (It needs to allow cross-origin access via CORS, or you can simulate using --disable-web-security, which is definitely not recommended when visiting any real sites.)

The HTTP Auth interstitial is shown during the XHR while the authentication dialog is up.  That's somewhat expected, and I could go either way on whether it's a bug.  We don't wan the user to be confused about where the password is going.

The problem is that the HTTP Auth interstitial does not go away afterwards in the XHR case!  This is true whether the authentication succeeds, fails, or is canceled.  The original page is still there under the interstitial, but the user can't see it until they click back.  That's pretty bad.

I'm not sure what the plan is for the HTTP Auth interstitial as we move most interstitials from overlays to committed pages in issue 448486.  If the HTTP Auth interstitial is becoming a committed page as well, that would break this XHR case.

meacer@ and estark@, can you take a look to see what the correct behavior here should be?
Cc: carlosil@chromium.org
Hrm, we hadn't fully fleshed out the plan for HTTP auth interstitials yet, but I think we might have neglected to consider subresources/XHRs all together, and that may be a big glaring hole in the plan. If we could kill cross-origin HTTP auth prompts all together, that would really make life a lot easier, but that doesn't look feasible: according to UMA that meacer added in issue 400380, >80% of HTTP auth prompts are for cross-origin subresources. :(
I think we can still block cross origin subresources and allow the user to override the block. I did some work on that a while ago and used the mixed content UI for a prototype implementation. Would finishing that work help here?
Ah, interesting. What would they see if they override the block? Would we still need the interstitial to blank out the underlying page?
> The HTTP Auth interstitial is shown during the XHR while the authentication dialog is up.  That's somewhat expected, and I could go either way on whether it's a bug.  We don't wan the user to be confused about where the password is going.

I believe this is the root cause of the bug. The interstitial was only intended for main frame navigations ( bug 149871 ). We don't show it for iframes, for example. The reason is the bad UX when we display a blank interstitial and hide it, while the user stays on the same page.

The code that decides whether to show the interstitial is at [0]. The problem here is that is_main_frame is true for subresources (XHR, <script> etc but not <img>) as well as main frame navigations, so both show interstitials. We should be consistent and do the same thing for both subresources and subframes: Either show the interstitial for both, or don't. 

> Ah, interesting. What would they see if they override the block? Would we still need the interstitial to blank out the underlying page?

The UI would allow the user to enable cross origin HTTP auth dialogs on the main page's origin and would require a reload, similar to mixed content blocking. Once the user reloads, I don't think we need to show an interstitial. It was intended to prevent drive by http-auth navigations with dialogs overlaying the original page, which is not the case here.

So we probably need something like this:
1. Block all cross origin subframe and subresource HTTP auth prompts and provide a UI override (Currently, only <img> subresources are blocked with no override).
2. Do not show interstitials for subframe and subresources when the user overrides the block

For (2) we'll need to find a way to distinguish between subresource requests and navigations in LoginHandler, not sure how feasible that is.

[0] https://cs.chromium.org/chromium/src/chrome/browser/ui/login/login_handler.cc?rcl=6838ddb654b67d5e823e50906c6aec274cdad1e1&l=641
Comment 10: I like that plan.  Seems like you might be able to change the is_main_frame bit to is_main_frame_navigation by doing a better check in ResourceDispatcherHostImpl::CreateLoginDelegate and NetworkServiceClient::OnAuthRequired (using resource_type), but that's just a first glance.
I looked at  issue 840176  today and it seems similar to this. Is it possible that this is also a recent regression? Maybe doing a bisect back to M64 or M65 can be a useful step.
FYI: The  issue 840176  has been fixed on master branch and merged to M67 branch. So maybe can try again to see if this issue still can be reproduced.
Cc: juncai@chromium.org
Labels: Hotlist-ConOps
Mergedinto: 840176
Status: Duplicate (was: Assigned)
juncai: Thanks for taking a look!

I did a bisect [*] and can confirm this was fixed by  issue 840176 , so duping into it.

I'll see if Comment #10 requires a separate bug.

* Range: https://chromium.googlesource.com/chromium/src/+log/8dc869e5d882d582a5c3e88c4c2bb4f75dfc6fb6..a95bed30479b9701ac3ccaf28b25550bd419a4cb

Sign in to add a comment