-
Notifications
You must be signed in to change notification settings - Fork 389
Description
Summary
When multiple client.goTo() calls happen in quick succession (e.g., redirect to homepage immediately followed by redirect to editor), both requests arrive at the server with no cookies. Each request independently tries to log the user in, setting different session cookies. The cookie store picks up cookies from both requests, including the interrupted one, which corrupts the session state and breaks nonces.
Steps to reproduce
- Call
client.goTo('/wp-admin/') - Immediately call
client.goTo('/wp-admin/post-new.php')before the first navigation completes - Observe that the session cookies get mixed up
Root cause
The data flow in this scenario:
- First request (homepage redirect) is sent with no cookies
- Second request (editor redirect) interrupts the first, also sent with no cookies
- Both requests independently hit the auto-login endpoint
- Both requests set different session cookies (
seccookie changes between them) - The
HttpCookieStoreinphp-request-handler.tsstores cookies from both responses, including the interrupted request - This corrupts the session - nonces generated by one request don't match the session established by the other
With regular browser cookies, you'd simply get logged out (clearly indicating something is wrong). But because we use a custom cookie store that accumulates cookies from all responses, we end up with a corrupted but "logged in" state.
Relevant code
packages/php-wasm/universal/src/lib/http-cookie-store.ts- stores cookies from all responsespackages/php-wasm/universal/src/lib/php-request-handler.ts:665-668- callsrememberCookiesFromResponseHeadersafter every request
Possible solutions
-
Don't store cookies from interrupted/cancelled requests - Track which requests are still "active" and only persist cookies from completed navigations
-
Await navigation completion after every
goTo()call - Callers should wait for the iframe to fully load before issuing anothergoTo(). This is a usage pattern fix rather than a Playground fix. -
Implement request sequencing - Queue
goTo()calls so they execute one at a time, preventing overlapping requests -
Add request correlation to cookie storage - Associate cookies with specific request IDs and only keep cookies from the "winning" request in case of races