Skip to content

epic(security): pre-authz existence oracles / info-leak — order authorization before existence checks #327

Description

@EricAndrechek

Area: api · policy — security (pre-authz existence oracles / info-leak) · found via pre-launch audit

Umbrella for the enumeration / info-disclosure findings from the 2026-06-09 audit. The common root is existence / validation checks running before authorization, so an anonymous caller can distinguish "exists but forbidden" (403) from "doesn't exist" (404/400) and enumerate names/values it shouldn't see. The fix pattern is uniform — authorize before existence, and return an indistinguishable response for forbidden-vs-absent. Promote each checklist item to its own issue when picked up.

Checklist:

  • Unauthenticated column-name oraclevalidateColumn (400 "unknown column") runs before authorize (403 "not allowed"), so an anon caller reconstructs the full physical column list of any readable table, including columns withheld from public (e.g. a future telemetry table's hidden IP/geo columns).
  • Unauthenticated pipe-name oracleStore.Get (404) before the RoleAllowed (403) gate; latent here (all pipes are [public], so the live signal is only 200-vs-404) but enumerable across roles for any future private pipe.
  • Token-validity oracle on admin routes — no-token→403 vs present-but-bad-token→401 discriminates expired/invalid/absent; arguably working-as-designed (deliberate "bad token fails loud", Key Decision docs: add initial Astro-based documentation site #7) but doubles as a JWT-format recon signal — decide whether to unify.
  • Anonymous value/count oracle on allowed columns — the public grant permits arbitrary eq/like/in + count, i.e. an unthrottled boolean/substring scrape over the real corpus; low today (data is public) but a PII oracle the instant a sensitive column joins a public allow-set (ties the rate-limit item in the DoS epic).

Related: #260 (the table-name oracle — already filed, same root: schema-existence 404 echoing the name before authz), #214 (per-table policy scopes), the DoS / resource-exhaustion hardening epic (the value/count scrape also needs rate-limiting).


From WaveHouse-Stats pre-launch security audit (WAVEHOUSE-FEEDBACK.md dogfooding), audited dev 60fed15 / enum-pass 0b62271 (2026-06-10). Filed via /pm-triage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/apiHTTP handlers, routing, middlewarearea/policyAccess control policies (Hasura-style)breaking-changeBreaking change to public API, CLI, or configenhancementNew feature or requestsecuritySecurity-sensitive issue or fix

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions