Document three published advisories in security notes

Add user-facing security notes for the three advisories published on
2026-07-09: the ADMIN-to-OWNER privilege escalation via createUser
(GHSA-cppp-g98f-gfpp), the unauthenticated cross-tenant and
hidden-item disclosure via Query.node in the Trust Center API
(GHSA-w23w-f7v2-625w), and the broken access control in the public
e-signature NDA API (GHSA-22xj-f767-ppw6). Each note summarizes the
flaw and the shipped remediation and credits the reporter.

Also backfill the advisory and CVE references on the existing open
redirect note, which already had a fix but no published identifiers.

Signed-off-by: Sacha Al Himdani <sacha@probo.com>
This commit is contained in:
Sacha Al Himdani
2026-07-09 12:24:12 +02:00
parent 920cbb0a26
commit eb9274f2cd

View File

@@ -3,6 +3,77 @@
User-facing notes on security-relevant changes to Probo. For the
vulnerability reporting process, see [SECURITY.md](SECURITY.md).
## Privilege escalation to OWNER via createUser
_2026-07-09, IAM_
Promoting a membership to OWNER is an owner-only action, and
`updateMembership` enforced it. The `createUser` mutation (and its MCP
`CreateUserTool` twin) created a membership with a caller-chosen role
but only authorized `iam:membership-profile:create`, which ADMIN holds,
and never re-checked the owner-only gate. An organization ADMIN could
therefore call `createUser` with `role: OWNER` and an attacker-controlled
email, activate it through the normal invitation flow, and gain full
OWNER privileges (organization deletion, SAML/SSO and SCIM configuration,
owner promotion/demotion) that ADMIN is explicitly denied.
Both `createUser` entry points now enforce the owner-only authorization
when the requested role is OWNER, mirroring `updateMembership`. Ownership
grants were subsequently consolidated into fail-closed allow/deny IAM
policies (keyed on the requested `target_role`) so that granting OWNER
fails closed across every membership-creating and membership-updating
path.
Reported by [Pig-Tail](https://github.com/Pig-Tail).
([GHSA-cppp-g98f-gfpp](https://github.com/getprobo/probo/security/advisories/GHSA-cppp-g98f-gfpp))
## Cross-tenant and hidden-item disclosure via Query.node in the Trust Center API
_2026-07-09, Trust Center_
The public Trust Center GraphQL API exposed `Query.node(id:)` with
optional authentication. Six of its type branches (`Organization`,
`Framework`, `Audit`, `ThirdParty`, `TrustCenter`, and
`TrustCenterReference`) derived their tenant scope from the
client-supplied GID and loaded the object with no comparison to the
visited trust center's organization and no visibility filter. An
unauthenticated visitor who held a target GID could read items hidden
from that trust center, and objects belonging to any other organization
(including orgs with no published trust center), leaking names,
descriptions, contact details, and connected items.
Every trust API resolver now derives its scope from the active
compliance page's organization via `compliancepage.ScopeFromContext`,
so reads are confined to the page's tenant. Cross-tenant or unknown IDs
surface as not-found instead of leaking data.
Reported by [Pig-Tail](https://github.com/Pig-Tail).
([GHSA-w23w-f7v2-625w](https://github.com/getprobo/probo/security/advisories/GHSA-w23w-f7v2-625w))
## Broken access control in the public e-signature NDA API
_2026-07-09, Trust Center_
The public Trust Center mutations `acceptElectronicSignature` and
`recordSigningEvent` were gated only by session presence. The underlying
`esign` service built its tenant scope from the client-supplied
`signatureId` and never verified the signature belonged to the caller.
Any self-provisioned trust center visitor holding another visitor's
signature GID could complete that visitor's NDA signature (overwriting
signer name, IP, and user agent, and triggering certificate sealing) or
inject arbitrary audit-trail events, defeating the non-repudiation and
integrity guarantees of the e-signature system.
The `esign` signature operations now take a caller-provided scope rather
than deriving one from the requested ID, and `AcceptSignature` /
`RecordEvent` verify signature ownership within scope before acting. The
signer and actor emails are always derived from the verified session
identity, never client input, and are compared against the signature's
stored `SignerEmail`.
Reported by [Pig-Tail](https://github.com/Pig-Tail).
([GHSA-22xj-f767-ppw6](https://github.com/getprobo/probo/security/advisories/GHSA-22xj-f767-ppw6))
## Cross-tenant IDOR via unvalidated foreign-key references
_2026-07-03, GraphQL_
@@ -65,6 +136,8 @@ which browsers can treat as an external redirect.
Reported by [Fushuling](https://github.com/Fushuling) and
[RacerZ](https://github.com/RacerZ-fighting).
([GHSA-x7qq-m748-8p2c](https://github.com/getprobo/probo/security/advisories/GHSA-x7qq-m748-8p2c),
[CVE-2026-49820](https://www.cve.org/CVERecord?id=CVE-2026-49820))
## Password changes invalidate existing sessions