Skip to content

Harden page ownership: only the RPC session that owns a pageId can push or forget it #309

Closed

Description

@erkamyaman

Problem

Every inspector on the devframe server (packages/devtools/src/devframe.ts) trusts the pageId that comes with a report. Any trusted RPC client can send a push or a forget for any pageId, including one that another session reported. That client can overwrite another tab's data or remove it.

This came up in review of #308 for the Capacitor reports. The same pattern is in every inspector: components, signals, injectors, router, NgRx, pipes, SSR & HTTP, highlights and Capacitor.

It is low risk today, because only an authenticated client can call these RPCs. It is still worth closing, so that one bad or buggy client cannot change another page's data.

Why it was not fixed in #308

The obvious fix is to reject a report whose pageId is bound to another session. That breaks reconnects. The overlay keeps its pageId in sessionStorage, so a reloaded or reconnected page comes back with the same pageId on a new RPC session. The old session may not have closed yet. A strict rule would then drop the page's own reports until the old binding expires.

Proposal

  • One shared ownership helper in packages/devtools/src/rpc/, building on trackPageSessions (rpc/page-sessions.ts), used by every inspector instead of ad hoc checks.
  • A clear takeover rule for a reconnecting page. Options to decide:
    • the new session takes over when the old session is closed or has gone quiet past the page expiry;
    • the overlay sends a per-page secret, minted with the pageId and kept in sessionStorage, and only a session that shows it can take over;
    • or both.
  • Forget and clear RPCs follow the same rule.
  • The panel and agent tools are not affected. They read pages and do not report them.

Done when

  • Every inspector's push, forget and clear handlers go through the shared helper.
  • Tests cover: a push for another session's page is ignored, a reloaded page takes over its own pageId, and two tabs never overwrite each other.
  • docs/contributing/coding-standards.md (the pageId section) and apps/docs/src/content/security.md describe the rule.

Activity

  1. self-assigned this
    on Oct 11, 2026
  2. added a commit that references this issue on Oct 12, 2026
    deebefb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions