fix(cookies): repair StorageActor enumeration on FF152 (httpOnly + flags) - #160
Merged
Merged
Conversation
…ags)
On Firefox 152 the cookies `resources-available-array` event arrives
*before* the `watchResources` ACK. `recv_reply_from` routes any typed
packet to the transport's event sink and returns only the plain ACK, so
on the direct `cookies` command path (no sink installed) the event was
dropped entirely — `getStoreObjects` was never sent, `list_cookies`
returned empty, and every cookie silently fell back to `document.cookie`
(missing httpOnly cookies and nulling secure/sameSite/domain flags).
`cookies --storage-only` returned 0. Confirmed via raw RDP tracing on a
clean FF152.0.6 instance (dogfooding-session-61).
Theme A: `StorageActor::list_cookies` now installs a temporary event-sink
collector around the `watchResources` call via the new
`RdpTransport::swap_event_sink` (restoring any prior sink afterwards),
then finds the cookie store resource from the captured events first,
falling back to the inline ACK and one extra `recv()` for older Firefox
message orderings. The FF152 resource/getStoreObjects wire contract is
unchanged — the fix is purely the event-capture ordering.
Theme B: `commands::cookies::run` attaches a
`warnings[{type:"storage_actor_empty"}]` marker (via
`attach_storage_degraded_warning`) when the StorageActor enumeration is
empty but `document.cookie` still contributed entries, so a degraded
result is never presented as complete.
Verified live on FF152: an httpOnly `secret` cookie set via `Set-Cookie`
is now enumerated with isHttpOnly/isSecure/sameSite; `cookies
--storage-only` returns >= 1. Recorded a real FF152 fixture.
Tests:
- live_cookies_httponly_enumerated, live_cookies_storage_only_nonempty
- parse_cookie_store_resource_ff152_shape,
swap_event_sink_returns_previous_and_installs_new
- unit_cookies_storage_degraded_warning_attached (+ two no-warning cases)
- recorder live_cookies_httponly +
get_store_objects_cookies_httponly_response.json fixture
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…arning iter-121 found FF152 can deliver a resources-available-array event before the watchResources ACK, which a naive read-ACK-then-maybe-read-one-more pattern silently misses. iter-122's dom-complete wait subscribes to document-event via the same watch_resources path, so before assuming the event "never fires" (Theme A), root-cause with a raw RDP trace and consider RdpTransport::swap_event_sink as the capture primitive.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements iteration 121. On Firefox 152 the
cookiescommand silently lost its authoritative StorageActor path — httpOnly cookies were missed entirely andisSecure/isHttpOnly/sameSite/domainwere always null;cookies --storage-onlyreturned 0. Confirmed on a clean FF152.0.6 instance in dogfooding-session-61.resources-available-arrayevent arrives before thewatchResourcesACK.recv_reply_from(iter-74+) routes any typed packet to the transport's event sink and returns only the plain ACK. On the directcookiescommand path no sink is installed, so the event was dropped entirely —getStoreObjectswas never sent,list_cookiesreturned empty, and every cookie fell back todocument.cookie(exit 0, silently wrong). The FF152 wire contract for the cookie resource andgetStoreObjectsis unchanged; the bug is purely event-capture message-ordering.StorageActor::list_cookiesnow installs a temporary event-sink collector around thewatchResourcescall via the newRdpTransport::swap_event_sink(restoring any prior sink), finds the cookie store resource from captured events first, then falls back to the inline ACK and one extrarecv()for older Firefox orderings.commands::cookies::runattaches awarnings[{type:"storage_actor_empty"}]marker (attach_storage_degraded_warning) when the StorageActor path is empty butdocument.cookiestill contributed entries, so a flag-less result is never presented as complete.kb/rdp/actors/storage.mdrecords the FF152 root-cause analysis, the parent-process cookies architecture, and the fix.Test plan
live_cookies_httponly_enumerated— after aSet-Cookie: …; HttpOnly; Secure; SameSite=Strict,ff-rdp cookiesreturns the cookie withisHttpOnly==trueand non-nullisSecure/sameSite, not sourced fromdocument.cookie. PASS live on FF152.0.6.live_cookies_storage_only_nonempty—ff-rdp cookies --storage-onlyreturns>= 1on a page that set a cookie. PASS (returned 2).parse_cookie_store_resource_ff152_shape— parser handles the exact FF152 resource event (withbrowsingContextID/resourceKey).swap_event_sink_returns_previous_and_installs_new— new transport helper preserves/restores the prior sink.unit_cookies_storage_degraded_warning_attached+ two no-warning cases — Theme B marker logic.live_cookies_httponly+ real recorded fixtureget_store_objects_cookies_httponly_response.json.cargo fmt/cargo clippy --workspace --all-targets -- -D warnings/cargo test --workspace -qall clean.cargo run -p xtask -- check-iteration-ready→ 10/10 PASS.🤖 Generated with Claude Code## Claims vs code
<generated 2026-07-19T11:10:07Z by ralph-loop>
StorageActor::list_cookies→ ✅ matched in diffRdpTransport::swap_event_sink→ ✅ matched in diff