Skip to content

servo web capture: cookie state persists across unrelated capture sessions #666

Description

Reproduction

In one long-lived skit process:

  1. Run a oneshot capture of a consent-bearing page with the prototype custom_js clicker and click Agree.
  2. Run a later, unrelated oneshot capture of the same page without the clicker.
  3. The later session no longer shows the consent banner.
  4. As a control, run two consecutive captures without clicking; the banner remains in both.

This was reproduced across separate oneshot sessions in the same skit process.

Finding

The native Servo plugin creates one Servo with ServoBuilder::default().build() for the shared Servo thread, and reuses that process-wide Servo for all WebViews/instances. Servo creates its public HTTP resource threads and cookie jar when that Servo is built. The public HttpState owns an in-memory CookieStorage (servo-net ResourceChannelManager::create_http_states); it is not stored in InstanceState and is not reset when a WebView/oneshot instance is destroyed.

The plugin does not set Servo Opts.config_dir or temporary_storage, so there is no configured profile directory for this path. With the default config_dir: None, the cookie jar is process-wide for the shared Servo instance (and in-memory), not per capture instance.

Impact

A capture of an authenticated or consent-bearing page can influence a later unrelated capture in the same process. That is the same trust boundary the existing cross-session pixel-isolation tests were written to protect, but this leak is stateful rather than visual.

Suggested regression test

Use a local test origin with a consent endpoint/page whose response or DOM depends on a cookie. In one shared Servo/skit process, run: (a) a capture that sets the cookie, then an unrelated capture that asserts the banner/state is still present; and (b) two captures without setting the cookie as a control. Assert DOM/cookie state or response behavior, not pixels. The test should create fresh capture instances while retaining the shared Servo thread so it exercises the production scope.

The fix likely needs an explicit per-session storage/profile boundary or a documented isolation/reset operation; this issue is intentionally tracking the scope decision separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions