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

Issue 903737 link

Starred by 2 users

Issue metadata

Status: Started
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 3
Type: Bug



Sign in to add a comment

HTTP auth dialog comes up multiple times

Reported by ha...@hboeck.de, Nov 9

Issue description

Chrome Version       : 71.0.3578.30
OS Version: Gentoo Linux
Other browsers tested:
    Firefox:OK
    IE/Edge:OK

What steps will reproduce the problem?
1. Run a page with multiple resources (images, CSS, JS) behind HTTP basic authentication.
2. Open the page, type in username and password.

What is the expected result?
HTTP authentication dialog should appear once.


What happens instead of that?
HTTP authentication dialog opens up multiple times.


Please provide any additional information below. Attach a screenshot if
possible.

UserAgentString: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.30 Safari/537.36


I run a nonpublic wiki (mediawiki) behind an HTTP basic authentication protection. The password for the HTTP authentication is stored in Chromium's password manager.
Opening the page should ask for the username/password once and then just load the page. Yet during page load the HTTP login dialog appears multiple times.

It seems that there is some kind of race condition where requests to subresources like images aren't sent with the HTTP auth credentials.

Usually I get three login dialogs, but this is a bit irregular and not 100% reproducible. Notably while the first two dialogs have the username/password pre-filled (as it's stored in the browser), the third one does not. It seems that this non-filled dialog is for the request for the favicon.
 
Components: Internals>Network>Auth
Labels: Needs-Triage-M71
Cc: krajshree@chromium.org
Labels: Needs-Feedback Triaged-ET
hanno@ - Thanks for filing the issue...!!

Could you please provide a sample test file/url to test the issue from TE-end.
This will help us in triaging the issue further.

Thanks...!!
I've setup a similar scenario:
https://doublehttpauth.int21.de/

Username guest, password guest. Behind the http auth is a plain/fresh installation of mediawiki.

In my experience this bug reproduces better if the browser was already running/used for a while.
Project Member

Comment 5 by sheriffbot@chromium.org, Nov 14

Labels: -Needs-Feedback
Thank you for providing more feedback. Adding the requester to the cc list.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Cc: phanindra.mandapaka@chromium.org
Labels: -Pri-3 Target-72 M-72 FoundIn-71 FoundIn-70 FoundIn-72 OS-Mac OS-Windows Pri-2
Status: Untriaged (was: Unconfirmed)
As per comment #4, Able to reproduce the issue on reported chrome version 71.0.3578.30 also on latest chrome 72.0.3611.0 using Mac 10.14.0, Ubuntu 17.10 and Windows 10.  
 
Same behavior is seen on M60(60.0.3112.113) hence considering it as non-regression and marking it as Untriaged.

Thanks! 
Components: Internals>Network>HTTP2
We're removing the auth entry from the cache because we think we send headers but receive a challenge.  I think the reason is most likely because the server pushes a resource with the path /resources/assets/wiki.png?de8c8, and the pushed headers are an auth challenge, though I'm not positive that's the problem.  Maybe try disabling that, and see if there's no second dialog?
Labels: Needs-Feedback
Going to add Needs-Feedback, since I'd appreciate a check that removing the push (Or not pushing an error page) does indeed fix this, though I think we're at a point where the H2 and auth owners could decide if we want to do something different in this case.

I assume what's happening in that we opportunistically attach auth headers to the request, then at the H2 layer, the request (with the auth headers) is matched to the push stream (with the auth challenge).  The layer just above, which is the one that deals with auth, then determines that it received a challenge despite the auth header it just attached, so they were not correct credentials (Despite the headers not actually being sent over the wire, due to the push).

Comment 9 Deleted

I am able to reproduce, have to enter credentials three times.  See attached NetLog, HTTP2_SESSION source id 386449.  Just like suspected in comment #7, there is a pushed response on stream 2, with the pushed response headers including www-authenticate.  I do not immediately understand how the pushed stream is causing the issue though.  This is what I see in chronological order.

1. Stream id 2 is pushed on stream 5.
2. Response headers arrive for stream 2.
3. This pushed stream is matched with a request.  Unfortunately request headers are not logged.
4. Another request is sent for the same URL on stream 19 with appropriate authorization request header.
5. Response arrives on stream 19 without any auth headers.

There is no other activity for this URL (other than being mentioned on stream 5 as link: rel=preload).
903737 chrome-net-export-log.json
482 KB View Download
With push disabled, I only need to enter credentials once.
With push enabled, I need to enter credentials three times.

Tried five times both scenarios (always restarting the browser, in incognito mode), reproducible without a miss.

Maybe Chrome should reject pushed streams if the pushed response has an auth header?  That would certainly solve the issue, but I wonder if there is a smarter way of matching that would just make this magically work with push.
Components: Internals>Network>QUIC
Labels: -Pri-2 -Needs-Feedback Pri-3
Talked to Asanka about this as well - we think that perhaps we should reject all pushes that aren't 2xx/3xx responses.  We could reject 304s, too, since pushing those is kinda weird, but probably not worth the effort.  This presumably applies to QUIC as well.

I'm lowering the priority, since this seems like a server bug (Pushing a challenge is a bit weird), but do think it's worth handling this case in Chrome.

Another option would be to hard-fail in this case with another error, to help people catch this server issue, but not sure that's worth the issue, and a bit reluctant to defacto ban this behavior, because maybe there are some sort of sane use cases I'm missing, and we'd want to support later (And wouldn't want to prevent other browsers from supporting).
This is standard apache httpd, so if this is a server bug it's a bug in apache.
You didn't have to manually configure server push and pick what URLs to push when?
No, I never configured anything alike. But it seems apache has some automatism to do this:
https://httpd.apache.org/docs/2.4/howto/http2.html#push
Hanno gave me a heads up on this ticket. I am the dev for h2 in Apache.

The default behaviour in Apache is to enable push and use "Link" headers from the application responses to trigger pushes. It seems in this case, the app sends preload
links to resources which are also configured to be restricted by http auth.

The reason push is not auto-disabled for auth resource is that the decision to push is done before the URL of the pushed resource is resolved against httpd's internal handlers. In short, it is unknown that the resources have auth protection. Once it is known, the server either sends the 401 or resets the push stream. Would you prefer the latter? What would the user experience of that be?

In general, pushes of challenges, will be rare, but are probably hard to avoid. Think of a reverse proxy that wants to push from the edge.
#16: Thanks for chiming in! Not sending the 401 would be better.

Either way Chrome needs to handle the possibility that servers will send similar non-cacheable responses. Hence the proposal to disregard responses that are not 2xx/3xx.

A "Vary: Authorization" in the PUSH_PROMISE frame from Apache would work around this - normally, browsers don't cache auth challenges, but pushes are implicitly cached responses, which have basically forced HTTP cache semantics.
Owner: b...@chromium.org
Status: Assigned (was: Available)
Regarding comment #16: If the push stream is reset before Chrome matches it with a request, that's as if it never was there.  If the reset frame arrives after, that's as if a regular server response was reset.  I guess the retry logic would paper over that but I'm not sure.

Regarding comment #18: I can confirm that Vary header matching is implemented in Chrome, so that sounds like a good option.

At the same time, I agree that Chrome should disregard responses with status code other than 2xx/3xx.
[bnc]:  I'm not familiar with the push code, but if it's possible for us to match a stream request with a pushed stream that hasn't yet received push response headers, then we'll need special handling to either un-match that case, or not match requests to pushed streams without response headers yet.
Re comment #20: async matching has been implemented at  issue 554220 , so this is not a problem.  It was motivated by a number of other reasons the response headers were needed to make a decision on matching.
Status: Started (was: Assigned)

Sign in to add a comment