NewN-Day-BenchView benchmark
winfunc
Back to Hacktivity

Status: Patched

This vulnerability has been verified as resolved and deployed.

Formbricks logo
FormbricksHigh2026-07-30

Feedback Records gateway accepts organization permissions across tenants

Summary

Organization-scoped API-key flags were evaluated without binding the target directory's organization

A holder of an API key for organization A could select an active feedback directory belonging to organization B and list, search, create, update, or delete its feedback records according to A's organization-level permissions.

Root cause. The gateway resolved the target directory's authoritative organizationId, but the API-key branch called hasApiKeyImplicitFeedbackDirectoryAccess() without passing or comparing it. A's organizationAccess.accessControl flags were therefore treated as global.

Remediation evidence. Formbricks accepted the disclosure and opened the exact issue-tracked remediation after it. PR #8648 merged on 30 July 2026 and requires organization equality plus matching workspace permissions before the privileged Hub proxy path is allowed.

CVSS Score

VectorN
ComplexityL
PrivilegesL
User InteractionN
ScopeU
ConfidentialityH
IntegrityH
AvailabilityL
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L

Vulnerability Location

SourceLine 219
apps/web/modules/hub/feedback-records-gateway.ts
resolveTenantId()
SinkLine 299
apps/web/modules/hub/feedback-records-gateway.ts
authorizeFeedbackRecordsGatewayRequest()

Source-to-Sink Analysis

1
apps/web/modules/hub/feedback-records-gateway.ts:219

The authenticated caller selects the target feedback directory through tenant_id or the record path.

TYPESCRIPT
const tenantId = parseTenantId(
  originalUrl.searchParams.get("tenant_id")
);
2
apps/web/modules/ee/feedback-directory/lib/feedback-directory.ts:115

The server loads the selected directory and learns its real organization and workspace assignments.

TYPESCRIPT
prisma.feedbackDirectory.findUnique({
  where: { id: directoryId },
  select: { organizationId: true, workspaces: true },
});
3
apps/web/modules/hub/feedback-records-gateway.ts:192

The vulnerable helper accepted the attacker's own organization-level flag without comparing it to the target owner.

TYPESCRIPT
const acl = authentication.organizationAccess?.accessControl;
if (acl?.write) return true;
if (acl?.read && requiredPermission === "read") return true;

Impact Analysis

Critical Impact

The attacker can disclose substantial cross-tenant feedback datasets and, with write access, create, alter, or bulk-delete victim records. Feedback may contain survey text, user identifiers, and business metadata; availability impact is limited to the selected data.

Attack Surface

Formbricks Feedback Records gateway routes (/api/v3/feedbackRecords and /v1/feedback-records) when feedback directories and the Hub proxy are enabled.

Preconditions

The attacker controls a normal organization and one of its API keys with organization-level read or write access. They need a victim directory or record identifier, but no victim membership or platform-admin credential.

Proof of Concept

Environment Setup

Use an isolated affected Formbricks deployment with Feedback Directories, the gateway, and two organizations enabled.

Target Configuration

Give organization A an API key with organization-level read/write access and create an active feedback directory owned by organization B.

Exploit Delivery

Send GET /api/v3/feedbackRecords?tenant_id=<org-B-directory> with the organization-A API key, then repeat with a harmless test create/update/delete against seeded records.

Outcome

PR #8648 compares the authenticated and target organization IDs before evaluating permission weights, so every cross-organization request is denied.

Expected Response: The vulnerable gateway returns or mutates organization-B feedback instead of returning 403.

Run this level of analysis on your repo.

Winfunc traces source-to-sink paths, validates exploitability, and gives your team patch-ready remediation.

Vulnerability Detection