NewN-Day-BenchView benchmark
winfunc
Back to Hacktivity

Status: Patched

This vulnerability has been verified as resolved and deployed.

Vendure logo
VendureHigh2026-09-02

Channel-scoped administrators can read the global administrator directory

Summary

Resolver-level permission checks did not scope the selected Administrator rows

An administrator limited to one Vendure channel could list and retrieve administrators assigned exclusively to other channels, exposing staff names, email identifiers, role codes, permissions, and the global authorization structure.

Root cause. The GraphQL resolvers required ReadAdministrator only for the active request channel. AdministratorService.findAll() and findOne() then queried the global Administrator table without intersecting target roles and channels with the active user's authority.

Remediation evidence. GHSA-37j3-p93w-fq6w states that the issue was reported by the Winfunc Security Team on 17 July 2026 (report ASI7P966C). Vendure fixed it in 3.7.3 with commit 3bff2dd, which applies one visibility rule to administrator lists, direct reads, and dependent mutations.

CVSS Score

VectorN
ComplexityL
PrivilegesL
User InteractionN
ScopeC
ConfidentialityH
IntegrityN
AvailabilityN
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N

Vulnerability Location

SourceLine 40
packages/core/src/api/resolvers/admin/administrator.resolver.ts
AdministratorResolver.administrator()
SinkLine 95
packages/core/src/service/services/administrator.service.ts
AdministratorService.findOne()

Source-to-Sink Analysis

1
packages/core/src/api/resolvers/admin/administrator.resolver.ts:40

A channel-A administrator passes the channel token and satisfies ReadAdministrator on that active channel.

TYPESCRIPT
@Query()
@Allow(Permission.ReadAdministrator)
administrator(ctx, args) { return this.service.findOne(ctx, args.id); }
2
packages/core/src/service/services/administrator.service.ts:64

The vulnerable list query selected all non-deleted global administrator rows before pagination.

TYPESCRIPT
return this.listQueryBuilder.build(Administrator, options, {
  relations: ['user', 'user.roles'],
  where: { deletedAt: IsNull() },
  ctx,
}).getManyAndCount();
3
packages/core/src/service/services/administrator.service.ts:95

The direct lookup likewise constrained only the object ID and soft-delete state, not role/channel visibility.

TYPESCRIPT
repository.findOne({
  relations: ['user', 'user.roles'],
  where: { id: administratorId, deletedAt: IsNull() },
});

Impact Analysis

Critical Impact

The request breaks marketplace/channel confidentiality by disclosing the global privileged staff directory and role structure. Those identifiers can support targeted follow-on attacks, but this entry claims only the independently demonstrated cross-channel read impact.

Attack Surface

Vendure Admin GraphQL API deployments using multiple channels and channel-scoped administrator roles.

Preconditions

The attacker needs their own limited administrator account with ReadAdministrator on one channel. No cross-channel role, victim identifier, or SuperAdmin credential is required for the list path.

Proof of Concept

Environment Setup

Run Vendure before 3.7.3 with channel A and channel B, each with separate staff, plus a channel-A-only administrator.

Target Configuration

Grant the attacker ReadAdministrator only on channel A and keep the victim's roles exclusively on channel B.

Exploit Delivery

Authenticate as the attacker and query administrators { items { id emailAddress user { identifier roles { code permissions } } } } with channel A active.

Outcome

Vendure 3.7.3 filters lists before count/sort/pagination and makes direct lookup return no row unless the active user holds every permission of every target role on its channels.

Expected Response: The vulnerable build returns the channel-B administrator and role data in the channel-A response.

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