All Docs
FeaturesMaking Tax DigitalUpdated February 24, 2026

Security Advisory: Organisation Context (orgId) Accepted from Client-Controlled Cookie/Header

Security Advisory: Organisation Context (orgId) Accepted from Client-Controlled Cookie/Header

Version: 1.0.41
Severity: High
Class: Broken Object-Level Authorisation (BOLA) / Insecure cookie handling
Affected file: src/lib/trpc/trpc.ts


Overview

A security issue was identified in the way organisation identity (orgId) is resolved and trusted within the tRPC server context. Because orgId could be supplied directly by the client — both through an x-org-id cookie/header and through a procedure input override — the membership verification check could be manipulated to target organisations the attacker does not legitimately administer.

Additionally, the x-org-id cookie was being written client-side without the Secure flag on some code paths, weakening its integrity over non-HTTPS connections.


Technical Details

1. orgId Resolved from Client-Supplied Cookie/Header

The tRPC context (src/lib/trpc/trpc.ts) reads orgId directly from the incoming x-org-id cookie or HTTP header:

// Simplified illustration of the vulnerable pattern
const orgId = req.cookies['x-org-id'] ?? req.headers['x-org-id'];
ctx.orgId = orgId; // fully client-controlled

Because this value is set by the client, it cannot be trusted as a canonical authority for which organisation the session belongs to.

2. input.orgId Override in orgProcedure

orgProcedure — the tRPC middleware responsible for verifying organisation membership — also accepted input.orgId and used it to override the context-level orgId:

// Simplified illustration of the vulnerable override pattern
const resolvedOrgId = input.orgId ?? ctx.orgId;
await verifyMembership(userId, resolvedOrgId);

The membership check ran against the overridden value. Since input.orgId is entirely user-controlled, a user who is a legitimate member of at least one organisation could supply any arbitrary orgId through the procedure input and have it accepted.

3. Secure Flag Missing on Client-Side Cookie Assignment

In src/app/onboarding/page.tsx, the x-org-id cookie was set via document.cookie on the client:

// Vulnerable client-side cookie write (no Secure flag)
document.cookie = `x-org-id=${orgId}; path=/`;

Without the Secure attribute, this cookie can be transmitted over unencrypted HTTP connections, where it is visible to network observers.


Impact

  • A authenticated user who belongs to any organisation in the system could potentially read or write data belonging to other organisations by supplying a different orgId via procedure inputs.
  • On deployments not enforcing HTTPS end-to-end, the x-org-id cookie value could be intercepted in transit.

Remediation

Required Changes

src/lib/trpc/trpc.ts

  1. Remove the input.orgId override. The orgId used for authorisation must come solely from the server-resolved context — never from procedure input fields.
  2. Derive orgId from a server-set HttpOnly cookie only. The context should reject any orgId that did not originate from a cookie written by the server.
// Recommended pattern
// orgId is read ONLY from a server-set HttpOnly cookie — never from input
const resolvedOrgId = ctx.orgId; // set server-side, not overridable
await verifyMembership(userId, resolvedOrgId);

Cookie Attributes

The x-org-id cookie must be set server-side (e.g. in a Next.js API route or middleware) with the following attributes:

Set-Cookie: x-org-id=<value>; Path=/; HttpOnly; Secure; SameSite=Lax
AttributePurpose
HttpOnlyPrevents JavaScript (document.cookie) from reading the value, mitigating XSS-based theft
SecureEnsures the cookie is only transmitted over HTTPS
SameSite=LaxReduces cross-site request forgery risk

src/app/onboarding/page.tsx

Remove the document.cookie assignment for x-org-id. Replace it with a server-side API call (e.g. a POST to a Next.js route handler) that sets the cookie via a Set-Cookie response header with the attributes above.


Action Required for Self-Hosted Deployments

  1. Upgrade to v1.0.41 or later.
  2. Ensure all application traffic is served exclusively over HTTPS so that Secure cookie attributes are enforced.
  3. Review any custom tRPC procedures for patterns where input.* values are used to resolve the active organisation — these must be removed.
  4. Audit document.cookie usage across the front-end codebase and replace any security-sensitive cookie writes with server-side Set-Cookie headers.

References