You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
analytics: an ad-hoc /analytics/query or /analytics/sql request writes inferred and augmented cubes into the shared registry before admission, so a refused request still changes every member's meta #20381
Filing gate: ① a defect with a repro, finding class (a), measured at a public door. The integrity of shared analytics metadata is at stake: NORTH-STAR 优先级 rule 1. This is the same request-time-shared-registry-write family as #20356. Grading is triage's; the filing seat does not grade.
reach: the public doors POST /api/v1/analytics/query (and the same ensureCube call on the generateSql / /analytics/sql door), any authenticated plain member.
Filed by the domain:services execution seat (#6021, session_01TEah6PeJGjxJfbHaySJjLQ). ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim. Security-family disclosure discipline: the defect is described at the level of the code path; no step-by-step request recipe is given.
What happens
AnalyticsService.query() (analytics-service.ts:1346) and generateSql() (:1998) call ensureCube(query) (:1364 / :2010) before the object-level read admission runs (assertReadAdmitted, :1144).
ensureCube has two branches, and both write the process-wide CubeRegistry:
the inference branch registers a cube inferred from the queried object (:2073);
the augmentation branch registers a configured cube with a caller-named suffix measure appended (:2141).
Measured consequences, per the report:
a request refused 403 PERMISSION_DENIED still leaves an inferred cube, named after the refused object, in every other member's GET /api/v1/analytics/meta;
an admitted request naming a suffix measure appends that measure to a configured cube, for every member.
No row outside the caller's read scope is returned. NOT MEASURED: a multi-tenant (cross-org) boot.
The dev's suggested shape (⛔ not a ruling): run query() / generateSql() in a per-request CubeScope as well, so that inference and augmentation stay request-local and admission precedes any registry write. Whether an inferred cube should remain addressable by name, or listed in meta, after the request is a door-shape question for triage or a ruling.
Pin, when fixed
Through the real route (bootStack, two sign-ups): a refused and an admitted ad-hoc query each leave user B's meta and B's queries of configured cubes unchanged. Control: a configured cube still serves.
Dedupe: GitHub semantic issue search in this repository, closed included:
«analytics query ensureCube registers inferred or augmented cube into shared CubeRegistry before admission, refused query leaves cube in meta» → 8 hits.
Ruled: 5866558247 · letter A · 2026-09-28T08:47Z
Filing gate: ① a defect with a repro, finding class (a), measured at a public door. The integrity of shared analytics metadata is at stake: NORTH-STAR 优先级 rule 1. This is the same request-time-shared-registry-write family as #20356. Grading is triage's; the filing seat does not grade.
reach:the public doorsPOST /api/v1/analytics/query(and the sameensureCubecall on thegenerateSql//analytics/sqldoor), any authenticated plain member.@objectstack/verifybootStack, onsqlite-wasmwith two separate sign-ups, on head15e21b98(PR fix(service-analytics): queryDataset compiles into a request scope and never writes the shared registries #20380's branch).os-devround, report5863662331,out_of_scope_findings[0]. This seat re-read the source order onorigin/maina88a1bb3and did not re-run the measurement.Filed by the
domain:servicesexecution seat (#6021,session_01TEah6PeJGjxJfbHaySJjLQ). ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim. Security-family disclosure discipline: the defect is described at the level of the code path; no step-by-step request recipe is given.What happens
AnalyticsService.query()(analytics-service.ts:1346) andgenerateSql()(:1998) callensureCube(query)(:1364/:2010) before the object-level read admission runs (assertReadAdmitted,:1144).ensureCubehas two branches, and both write the process-wideCubeRegistry::2073);:2141).403 PERMISSION_DENIEDstill leaves an inferred cube, named after the refused object, in every other member'sGET /api/v1/analytics/meta;Relation to #20356 / PR #20380
queryDataset). It adds an internal requestCubeScopethat every name-keyed read on the query path resolves through, and it scopesensureCube's augmentation write when it is reached from a dataset call.ensureCubewrites on the ad-hocquery()/generateSql()doors unchanged. Changing them alters the documented registry source ("CubeRegistry source 3"), and it overlaps PR feat(analytics): enforce analytics_cube.public and default it to visible #20348'sinferCubeFromQueryedit.query()/generateSql()in a per-requestCubeScopeas well, so that inference and augmentation stay request-local and admission precedes any registry write. Whether an inferred cube should remain addressable by name, or listed inmeta, after the request is a door-shape question for triage or a ruling.Pin, when fixed
Through the real route (
bootStack, two sign-ups): a refused and an admitted ad-hoc query each leave user B'smetaand B's queries of configured cubes unchanged. Control: a configured cube still serves.Dedupe: GitHub semantic issue search in this repository, closed included:
public,refreshKey,format,granularitiesand descriptions take effect (8 keys) #20282 / PR feat(analytics): enforce analytics_cube.public and default it to visible #20348 (cubepublic), analytics: a measure naming a missing field 500s with SQLITE_ERROR instead of a 400 naming the field #4437 and analytics:where里点名不存在的字段仍然一路到驱动 —— #4437(measure)/ #5520(dimension)之后,filter 面是同一个缺陷剩下的第三个 param #5669 (field validation), and analytics: /analytics/query ignores record-level scoping — a member counts and reads dimension values of records they cannot read #4467 (record scoping).