Found while enumerating every meta read call site in packages/rest/src/rest-server.ts for #9454. ⛔ Not fixed there — filing rather than widening that card.
What was measured
#9454 threads the caller's active organization into the REST /meta read doors, so an org-authored overlay of an org-overridable type is served back. The enumeration classified 18 meta read call sites in rest-server.ts. Seventeen classify cleanly. One does not, and it is the only out-of-scope site that names an org-overridable type:
resolveFormBySlug, which backs the public GET /forms/:slug route, calls getMetaItems({ type: 'view', … }) with a hardcoded type: 'view'. view is allowOrgOverride: true, so this door can be asked for an item that lives in an org partition.
Why it was left alone rather than threaded
The route is deliberately anonymous. Its own TSDoc records that both public-form routes bypass enforceAuth even when anonymous-deny is on for the deployment, delegating security to the guest_portal permission set. Consistent with that, nothing in the whole forms region resolves an execution context — there is no resolveExecCtx call anywhere in it.
So there is no session-derived active organization to state. organizationIdForMetaRead('view', undefined) answers undefined at every call, and wiring it in would:
- change no behaviour for anonymous callers (the overwhelming majority on a public form), and
- add a session resolution to a route that deliberately performs none.
The actual gap, stated plainly
An organization that authors an overlay of a view backing a public form gets the env-wide version served to anonymous visitors. Their override is not applied on that route.
Closing that would mean deriving the organization from the host/environment rather than from the session — a different mechanism from the one #9454 uses, and a new resolution seam on a public path. That is a design question (which org owns an anonymous request on a multi-org deployment?), not a mechanical extension of #9454, which is why it is a separate card.
Not asserted
⛔ No claim that any tenant's data leaks here. The route reads the env-wide partition, which is the same thing every caller read before #9454. This is an unapplied override, not a disclosure.
Repo: objectstack. Site: packages/rest/src/rest-server.ts, resolveFormBySlug inside registerFormEndpoints (named by symbol — line numbers move).
Related: #9454.
Found while enumerating every meta read call site in
packages/rest/src/rest-server.tsfor #9454. ⛔ Not fixed there — filing rather than widening that card.What was measured
#9454 threads the caller's active organization into the REST
/metaread doors, so an org-authored overlay of an org-overridable type is served back. The enumeration classified 18 meta read call sites inrest-server.ts. Seventeen classify cleanly. One does not, and it is the only out-of-scope site that names an org-overridable type:resolveFormBySlug, which backs the publicGET /forms/:slugroute, callsgetMetaItems({ type: 'view', … })with a hardcodedtype: 'view'.viewisallowOrgOverride: true, so this door can be asked for an item that lives in an org partition.Why it was left alone rather than threaded
The route is deliberately anonymous. Its own TSDoc records that both public-form routes bypass
enforceAutheven when anonymous-deny is on for the deployment, delegating security to theguest_portalpermission set. Consistent with that, nothing in the whole forms region resolves an execution context — there is noresolveExecCtxcall anywhere in it.So there is no session-derived active organization to state.
organizationIdForMetaRead('view', undefined)answersundefinedat every call, and wiring it in would:The actual gap, stated plainly
An organization that authors an overlay of a view backing a public form gets the env-wide version served to anonymous visitors. Their override is not applied on that route.
Closing that would mean deriving the organization from the host/environment rather than from the session — a different mechanism from the one #9454 uses, and a new resolution seam on a public path. That is a design question (which org owns an anonymous request on a multi-org deployment?), not a mechanical extension of #9454, which is why it is a separate card.
Not asserted
⛔ No claim that any tenant's data leaks here. The route reads the env-wide partition, which is the same thing every caller read before #9454. This is an unapplied override, not a disclosure.
Repo:
objectstack. Site:packages/rest/src/rest-server.ts,resolveFormBySluginsideregisterFormEndpoints(named by symbol — line numbers move).Related: #9454.