Issue metadata
Sign in to add a comment
|
HTTP/2 PUSH_PROMISE frames are ignored (since 65.0.3302.0)
Reported by
niklas.a...@gmail.com,
Mar 13 2018
|
||||||||||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36 Example URL: - Steps to reproduce the problem: 1. A simple HTML page includes an additional resource (as <iframe>) 2. While handling the HTTP request for that simple page the server sends a PUSH_PROMISE to push the additional resource. What is the expected behavior? The browser does not send an request for the resource in the <iframe>, but uses the pushed resources. What went wrong? Chrome seems to ignore the PUSH_PROMISE and nevertheless sends out a request. (It does not reject the push by sending a RST_STREAM frame.) I attached the network log that shows that the PUSH_PROMISE frame has been received. From my point of view the PUSH_PROMISE matches the request that is later send out. Did this work before? Yes 65.0.3302.0 (Developer Build) (32-bit) (commit ecff233108ad7970d0fd4b37b694adecfef01a06 ) Chrome version: 65.0.3325.146 Channel: stable OS Version: 10.0 Flash Version: I tested it with developer builds: The server push works with 65.0.3302.0 (Developer Build) (32-bit). I downloaded this version from: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win/525952/ It does not! work with the version I downloaded here: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win/526003/ It seems like something was broken between commit ecff233108ad7970d0fd4b37b694adecfef01a06 and 772561ba831fa2ca15e0da4b34b0fcd977792d31.
,
Mar 13 2018
,
Mar 19 2018
The same thing happens on Linux.
,
Mar 20 2018
I'm puzzled by what seems to happen. Push still works for me on Chrome 65.0.3325.162 on https://http2-push.io. But I see that it does not work for you. Could you possibly set up a publicly available test site that I could use to reproduce and debug this issue? Thank you.
,
Mar 21 2018
I face similar issues on Mac. I use a basic HTTP/2 with push server implemented with Node. It used to work on Chrome 64, still working on Firefox but I'm not able to make it work with Chrome 65 (65.0.3325.181 to be precise). Here is a Gist of the server https://gist.github.com/Swiip/e56a521eae57f1d370780d0f718980a7 (sorry don't have something online) I confirm it currently works on https://http2-push.io with the same Chrome 65 so push is not totally broken.
,
Mar 22 2018
You’re right. This is strange. Push on https://http2-push.io works for me, too. I tried to replicate the test site from http2-push.io as accurately as possible but pushes from my server are still ignored. (Logs are attached.) BTW: If my server pushes one resource multiple times, the second push promises are rejected with an RST_STREAM. I’m going to try to set up a public test site. But unfortunately my server is proprietary software which is still in development. I’m not sure whether I’ll be able and/or allowed to do it.
,
Mar 22 2018
Is your localhost using an untrusted certificate (e.g. a self-signed one)? If so try to trust the certificate and see if that resolves the issue. See here: https://bugs.chromium.org/p/chromium/issues/detail?id=824988 Didn't mean to duplicate and I swear I searched for this before sunmitting, didn't find this issue, raised by own, then when I went back in to find my issue again, I found this one straight away and suspect it is a duplicate! Always the way :-( Thanks, Barry
,
Mar 23 2018
Yes, it's a self signed one and yes this was the cause of the problem. I'm definitely not an expert on certificates but I looked into it and realize that I could generate a "better" self signed certificate. I ended up here https://serverfault.com/questions/845766/generating-a-self-signed-cert-with-openssl-that-works-in-chrome-58 and generated a new one, and it finally works! Thanks a lot for the lead. There should be somewhere something which enforce security around http/2 push in the Chrome 65 release. I know I'm asking a lot but if in the future there was something to more precisely debug the push and the resolution of using or not what's was pushed, it would be wonderful.
,
Mar 23 2018
I actually used a signed and trusted certificate for my tests. But I checked it again and saw that my certificate was issued to “ABC.domain” while I of course accessed “abc.domain”. I repeated my test with a certificate that is issued to “abc.domain” and the server push works! After that, I repeated my test with a (signed and trusted) certificate that is issued to “*.domain”. => Pushes are ignored again. Is this behavior actually intended? I understand that pushes from untrusted servers should be ignored. But in my opinion the criteria for server push should not be more strict than the criteria on “TLS level”.
,
Mar 31 2018
As stated in this comment (https://bugs.chromium.org/p/chromium/issues/detail?id=824988#c4) which I'm now convinced is a duplicate of this issue, Chrome does not use caching when an untrusted certificate is used - even when clicking through. This is probably the cause of not being able to use HTTP/2 push since the push cache is not used. More detail here: https://bugs.chromium.org/p/chromium/issues/detail?id=103875
,
Apr 1 2018
,
Apr 12 2018
,
Apr 18 2018
As described in issue 110649 , resources from an origin with self-signed certificate are not cached in the HTTP cache. The same reasoning applies to push cache: an origin can have a self-signed certificate that is valid for some other domain. When the user clicks through the interstitial for that origin, they give permission to the origin to serve resources for that origin only, not any resource on any origin. If push was allowed for a connection with a self-signed certificate, then a single connection where the user clicked through the interstitial would be allowed to poison every single resource that browser profile requests (provided it can either guess requests or trick the user into requesting resources, which is trivial). This is a security hole we cannot bear.
,
Apr 18 2018
I agree that resources from an origin with untrusted self-signed certificates must not be cached. But as I tried to explain in comment 9, I’m able to reproduce the issue with trusted certificates. If I use a trusted certificate that is issued to “ABC.domain” (instead of “abc.domain”) or a trusted certificate that is issued to “*.domain”, server pushes are ignored. Both certificates are valid and the connection is shown as “secure” by Chrome. I suspect that those special cases are not checked for server push.
,
Apr 18 2018
Sorry, I overlooked that part. Indeed with a signed certificate for *.domain push should work.
,
May 9 2018
,
Jun 11 2018
Culprit is https://crrev.com/c/857278. Fix is on the way.
,
Jun 11 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/b2f7667286adf5feabb164f4ca8f5abbc7879e47 commit b2f7667286adf5feabb164f4ca8f5abbc7879e47 Author: Bence Béky <bnc@chromium.org> Date: Mon Jun 11 21:10:13 2018 Accept HTTP/2 pushed stream if SpdySessionKey matches. Before implementing cross-origin HTTP/2 server push, a request was simply served by an HTTP/2 connection (SpdySession object) choosen based on SpdySessionKey. (If such a connection existed. If not, we have IP-based pooling logic and other complications.) However, now that pushes are managed by Http2PushPromiseIndex, a request with secure scheme is only matched with a pushed stream if the connection's VerifyDomainAuthentication() accepts it. As a result of this, if a stream is pushed on a connection with a client certificate, a request is never matched with it, even if the SpdySessionKey matches, because SpdySession::CanPool() (called from VerifyDomainAuthentication()) returns false if a client certificate has been sent. Instead, the request ends up being sent over the very same connection where the pushed stream is waiting, which is admittedly silly. This CL allows a request to be served by a pushed stream on a connection if the SpdySessionKey is an exact match, regardless of what VerifyDomainAuthentication() would return. Add regression test SpdyNetworkTransactionTest.ServerPushWithClientCert. I locally verified that this test fails without the rest of the CL. Specifically it fails when trying to write a HEADERS frame on stream 3 on the existing connection, as described above. Add SpdyNetworkTransactionPushUrlTest.PushUrlTest/4 to document that cross-origin pushes on a connection with client cert are still rejected. This behavior does not change. I locally verified that this test passes without the rest of the CL. Bug: 821492 , 832859 Change-Id: Ie00958253c44209800ff3247716c1bfb8ad77e8d Reviewed-on: https://chromium-review.googlesource.com/1088990 Commit-Queue: Bence Béky <bnc@chromium.org> Reviewed-by: David Benjamin <davidben@chromium.org> Cr-Commit-Position: refs/heads/master@{#566146} [modify] https://crrev.com/b2f7667286adf5feabb164f4ca8f5abbc7879e47/net/spdy/spdy_network_transaction_unittest.cc [modify] https://crrev.com/b2f7667286adf5feabb164f4ca8f5abbc7879e47/net/spdy/spdy_session.cc [modify] https://crrev.com/b2f7667286adf5feabb164f4ca8f5abbc7879e47/net/spdy/spdy_session_key.cc [modify] https://crrev.com/b2f7667286adf5feabb164f4ca8f5abbc7879e47/net/spdy/spdy_session_key.h
,
Jun 14 2018
https://crrev.com/c/1088990 should fix this issue. Please try with Chrome version 69.0.3456.0 or above, and report back on this bug (or open a new one) if it still does not work.
,
Jun 28 2018
I tested it with version 69.0.3476.0 => Now server push works as expected with certificates assigned to "*.domain". Thank you for your help.
,
Jun 28 2018
Thank you for confirming. |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by mattm@chromium.org
, Mar 13 2018