Skip to content

graphql(ws): mutations ride the handshake-authenticated connection without per-operation binding #563

Open

Description

@beardthelion

The WebSocket GraphQL transport (server.rs, graphql_ws_handler) serves the full schema, including MutationRoot. graphql-ws authenticates the connection once at handshake; the signature binds nothing about subsequent operation payloads. A captured or replayed valid handshake therefore lets an attacker issue task mutations as that DID for the connection lifetime, subject only to the per-DID task authorization checks.

The DID propagation into request session data was added under #553 (read-side visibility gates), which is what makes authenticated WS operations possible, but whether mutations should ride WS at all is a contract question wider than that PR.

Proposed direction: reject mutation operations on the WebSocket transport while retaining authenticated reads and subscriptions. Removing the DID copy alone is not sufficient because resolvers can also read session data through ctx.data.

Surfaced by review on #553; flagged real but out of scope there.

Activity

  1. added
    kind:securityVulnerability fix or hardening
    sev:highMajor break or real security/trust risk, no easy workaround
    subsystem:apiNode REST API request/response surface
    subsystem:identityDID/UCAN, http-sig auth, push authorization
    on Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:securityVulnerability fix or hardeningsev:highMajor break or real security/trust risk, no easy workaroundsubsystem:apiNode REST API request/response surfacesubsystem:identityDID/UCAN, http-sig auth, push authorization

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions