WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
250781
COOP header breaks back/forward behavior when client-side redirects are involved
https://bugs.webkit.org/show_bug.cgi?id=250781
Summary
COOP header breaks back/forward behavior when client-side redirects are involved
David Dworken
Reported
2023-01-18 12:19:45 PST
While verifying the fix for a previous bug (
https://bugs.webkit.org/show_bug.cgi?id=237566
) I discovered what appears to be another bug in Safari's BFCache. Specifically, in some cases pressing the back button actually navigates back by two entries rather than one. So far I've been unable to create a minimal reproducer. The best reproduction steps I have are: 1. Close all other Safari tabs 2. Go to www.google.com 3. Search for "a" and click on the first result (wikipedia) 4. Wait 4-5 seconds 5. Press the back button Expected result: End up on the results page for the search query "a" Actual result: About half of the time, you'll end up back on www.google.com thereby skipping over a history entry I tested this in Safari 16.2 (18614.3.7.1.5) and in Safari Tech Preview (18615.1.17.6). It appears as though the Tech Preview release includes the fix for
https://bugs.webkit.org/show_bug.cgi?id=245912
so I believe this is not a duplicate.
Attachments
Add attachment
proposed patch, testcase, etc.
David Dworken
Comment 1
2023-01-18 12:21:25 PST
I'll also add that I believe (though I'm not 100% sure) that this seems to trigger more often if I use an intercepting proxy to set `COOP: same-origin-allow-popups` on the `www.google.com` responses.
David Dworken
Comment 2
2023-01-18 12:50:07 PST
I spoke too soon. I now can reproduce this non-flakily and can confirm that COOP is somehow tied to this. To reproduce non-flakily: 1. Close all other Safari tabs and wait a few seconds 2. Start mitmproxy with the script: ``` def response(flow): if 'www.google.com' in flow.request.host and not b'cross-origin-opener-policy' in flow.response.headers: flow.response.headers["cross-origin-opener-policy"] = "same-origin" ``` 3. Go to www.google.com 4. Search for "a" and click on the first result (wikipedia) 5. Press the back button Expected result: End up on the results page for the search query "a" Actual result: You'll consistently end up back on www.google.com thereby skipping over a history entry
Radar WebKit Bug Importer
Comment 3
2023-01-25 12:20:33 PST
<
rdar://problem/104659192
>
Chris Dumez
Comment 4
2023-01-31 14:34:44 PST
(In reply to David Dworken from
comment #2
)
> I spoke too soon. I now can reproduce this non-flakily and can confirm that > COOP is somehow tied to this. To reproduce non-flakily: > > 1. Close all other Safari tabs and wait a few seconds > 2. Start mitmproxy with the script: > > ``` > def response(flow): > if 'www.google.com' in flow.request.host and not > b'cross-origin-opener-policy' in flow.response.headers: > flow.response.headers["cross-origin-opener-policy"] = "same-origin" > ``` > > 3. Go to www.google.com > 4. Search for "a" and click on the first result (wikipedia) > 5. Press the back button > > Expected result: End up on the results page for the search query "a" > Actual result: You'll consistently end up back on www.google.com thereby > skipping over a history entry
I have been trying to reproduce via these steps but so far no luck. I am using `mitmdump -s add_coop.py` with add_coop.py containing: ``` def response(flow): if 'www.google.com' in flow.request.host and not b'cross-origin-opener-policy' in flow.response.headers: flow.response.headers["cross-origin-opener-policy"] = "same-origin" ``` When I load google.com, I can see `Cross-Origin-Opener-Policy: same-origin` on the network response via Web Inspector. However, when I search for "a", then click the wikipedia result and press the back button, I end up on the "a" search result page.
Chris Dumez
Comment 5
2023-01-31 14:43:10 PST
(In reply to Chris Dumez from
comment #4
)
> (In reply to David Dworken from
comment #2
) > > I spoke too soon. I now can reproduce this non-flakily and can confirm that > > COOP is somehow tied to this. To reproduce non-flakily: > > > > 1. Close all other Safari tabs and wait a few seconds > > 2. Start mitmproxy with the script: > > > > ``` > > def response(flow): > > if 'www.google.com' in flow.request.host and not > > b'cross-origin-opener-policy' in flow.response.headers: > > flow.response.headers["cross-origin-opener-policy"] = "same-origin" > > ``` > > > > 3. Go to www.google.com > > 4. Search for "a" and click on the first result (wikipedia) > > 5. Press the back button > > > > Expected result: End up on the results page for the search query "a" > > Actual result: You'll consistently end up back on www.google.com thereby > > skipping over a history entry > > I have been trying to reproduce via these steps but so far no luck. > > I am using `mitmdump -s add_coop.py` with add_coop.py containing: > ``` > def response(flow): > if 'www.google.com' in flow.request.host and not > b'cross-origin-opener-policy' in flow.response.headers: > flow.response.headers["cross-origin-opener-policy"] = "same-origin" > ``` > > When I load google.com, I can see `Cross-Origin-Opener-Policy: same-origin` > on the network response via Web Inspector. However, when I search for "a", > then click the wikipedia result and press the back button, I end up on the > "a" search result page.
I was using Safari Tech Preview 162.
David Dworken
Comment 6
2023-01-31 15:10:34 PST
I took another look at reproducing this and noticed that it seems to be dependent on there being multiple tabs open. I retested it on Safari Tech Preview 161 and with these steps I can consistently reproduce it: 1. Set up mitmproxy with the COOP script 2. Open a tab to example.com 3. Open a new tab to www.google.com 4. Search for "a" and click on the first result (wikipedia) 5. Press the back button 6. End up back on www.google.com Here is a video:
https://www.youtube.com/watch?v=amAF6-g0hVk
Karl Dubost
Comment 7
2023-06-11 18:30:32 PDT
Not able to reproduce so far with the steps given in
Comment #6
and Safari Version 17.0 (19616.1.15)
David Dworken
Comment 8
2023-07-13 11:19:24 PDT
Thank you for trying to reproduce! We also attempted to reproduce this issue with the latest version of Safari and could not reproduce it. But, we ran an experiment with enabling COOP for Google Search, which revealed a number of interesting metrics that seem to imply that there is still an issue with Safari’s COOP implementation. Comparing COOP enforced v/s in report-only mode, we see: * A 10% increase in the number of duplicate search queries issued within 5 minutes and a 62% increase in the number of duplicate secure queries issued within 1 second. This implies that either the page is failing to load or Safari is having to reload the page for some unknown reason. * A 5% decrease in BFCache hit rate. This implies that the BFCache may still be implicated. * A significant decrease in time-to-first-byte for search results pages. While normally this would be a positive change, we suspect that this decrease is somehow tied to the increase in duplicate queries (e.g latency going down since there are more duplicate requests). Based on this, we still believe that there is some sort of latent bug in Safari’s COOP implementation, and this makes us hesitant to roll out COOP enforcement for Safari users. Do you have any insights or suggestions on how we can proceed from here?
David Dworken
Comment 9
2023-08-31 12:23:40 PDT
After further investigation, we have come up with a minimal reproduction test case that demonstrates COOP changing the behavior of the back/forward button in the latest version of Safari. While this test case may seem convoluted, it is a direct corollary to a Google product where enabling COOP for Safari caused a breakage. The scenario is: 1. User is on some base page, that opens a popup to Page1 2. Page1 has a HTML form that auto-submits via JS to trigger a POST request to Page2 3. Page2 does a meta redirect to some final page 4. User hits the back button on the final page In this scenario, Safari will normally detect that Page1 and Page2 are redirects with no user interaction, and it will skip them when hitting the back button. Thus, hitting the back button will normally just close the popup. If COOP is enforced, Safari's heuristics here seem to fail which causes the user to get navigated back to Page1. Page1 then redirects the user to Page2 and then the final page, ultimately resulting in the user ending up on the same page as they started on, even when they hit the back button. You can observe this behavior by comparing the behavior of these two links in the latest version of Safari: *
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=unsafe-none
*
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=same-origin-allow-popups
Chris Dumez
Comment 10
2023-08-31 12:31:44 PDT
(In reply to David Dworken from
comment #9
)
> After further investigation, we have come up with a minimal reproduction > test case that demonstrates COOP changing the behavior of the back/forward > button in the latest version of Safari. While this test case may seem > convoluted, it is a direct corollary to a Google product where enabling COOP > for Safari caused a breakage. The scenario is: > > 1. User is on some base page, that opens a popup to Page1 > 2. Page1 has a HTML form that auto-submits via JS to trigger a POST request > to Page2 > 3. Page2 does a meta redirect to some final page > 4. User hits the back button on the final page > > In this scenario, Safari will normally detect that Page1 and Page2 are > redirects with no user interaction, and it will skip them when hitting the > back button. Thus, hitting the back button will normally just close the > popup. > > If COOP is enforced, Safari's heuristics here seem to fail which causes the > user to get navigated back to Page1. Page1 then redirects the user to Page2 > and then the final page, ultimately resulting in the user ending up on the > same page as they started on, even when they hit the back button. > > You can observe this behavior by comparing the behavior of these two links > in the latest version of Safari: > > * >
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=unsafe
- > none > * >
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=same
- > origin-allow-popups
Thank you for the test case. I can still reproduce with WebKit trunk. I'll investigate soon.
Chris Dumez
Comment 11
2023-08-31 16:00:09 PDT
(In reply to David Dworken from
comment #9
)
> After further investigation, we have come up with a minimal reproduction > test case that demonstrates COOP changing the behavior of the back/forward > button in the latest version of Safari. While this test case may seem > convoluted, it is a direct corollary to a Google product where enabling COOP > for Safari caused a breakage. The scenario is: > > 1. User is on some base page, that opens a popup to Page1 > 2. Page1 has a HTML form that auto-submits via JS to trigger a POST request > to Page2 > 3. Page2 does a meta redirect to some final page > 4. User hits the back button on the final page > > In this scenario, Safari will normally detect that Page1 and Page2 are > redirects with no user interaction, and it will skip them when hitting the > back button. Thus, hitting the back button will normally just close the > popup. > > If COOP is enforced, Safari's heuristics here seem to fail which causes the > user to get navigated back to Page1. Page1 then redirects the user to Page2 > and then the final page, ultimately resulting in the user ending up on the > same page as they started on, even when they hit the back button. > > You can observe this behavior by comparing the behavior of these two links > in the latest version of Safari: > > * >
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=unsafe
- > none > * >
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=same
- > origin-allow-popups
Looking at
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=same-origin-allow-popups
, it looks like only the page2 (with the meta redirect) actually serves the `coop: same-origin-allow-popups` header? The others seems to have `coop=same-
> origin-allow-popups` as GET parameter but don't actually serve the HTTP header.
Chris Dumez
Comment 12
2023-08-31 19:42:53 PDT
Pull request:
https://github.com/WebKit/WebKit/pull/17322
EWS
Comment 13
2023-09-01 09:12:25 PDT
Committed
267553@main
(268201eb1e94): <
https://commits.webkit.org/267553@main
> Reviewed commits have been landed. Closing PR #17322 and removing active labels.
David Dworken
Comment 14
2023-09-05 09:11:27 PDT
Wow, thank you so much for the quick fix! That is greatly appreciated and should enable us to safely enable COOP, so thank you!
> Looking at
https://pattern-dog-larkspur.glitch.me/safari-coop-bf-heuristic?coop=same-origin-allow-popups
, it looks like only the page2 (with the meta redirect) actually serves the `coop: same-origin-allow-popups` header? The others seems to have `coop=same-origin-allow-popups` as GET parameter but don't actually serve the HTTP header.
Yes, that is correct. The query param is just set for those other pages to enable it to be passed to page2.
Chris Dumez
Comment 15
2023-09-05 09:15:34 PDT
(In reply to David Dworken from
comment #14
)
> Wow, thank you so much for the quick fix! That is greatly appreciated and > should enable us to safely enable COOP, so thank you!
Thank you for coming up with a good reproduction case, it made a huge difference.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug