Skip to content

Security: share-link routes trust x-user-id/x-tenant-id headers (forge attribution, enumerate others' tokens) #2851

Description

@os-zhuang

Found by the ADR-0090 D10 adversarial security review. Same root cause as the settings-routes fix (#2848) — the raw-app route registration trusts identity headers.

What

packages/plugins/plugin-sharing/src/share-link-routes.ts:~37-46 uses a defaultContext that reads x-user-id / x-tenant-id from request headers, wired without a verified contextFromRequest (sharing-plugin.ts:~291). Registered on the raw Hono app with no auth middleware.

Impact

  • createLink stamps created_by: context.userId → a client can forge attribution to any user, and create links for any record of a publicSharing-enabled object (existence checked with SYSTEM_CTX, so the caller's own access is never verified).
  • GET /api/v1/share-links with X-User-Id: <victim>listLinks(createdBy: victim) enumerates another user's share-link tokens, which then resolve records via the public /:token/resolve endpoint under SYSTEM_CTX (RLS bypassed).
  • DELETE → revoke arbitrary users' links.

A separate, correctly-verified share-link handler exists in the dispatcher (http-dispatcher.ts:~3879, uses context.executionContext); the raw-app header-trusted route shadows it.

Fix direction

Same pattern as #2848: derive identity from the verified resolveAuthzContext (session/API-key/OAuth) instead of headers; make the default secure; verify the caller's own access to the record before createLink. Consider removing the raw-app route in favour of the verified dispatcher handler.

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions