Skip to content

proxy: redact row-security bound values from cost-estimate plan text #1094

Description

@babltiga

Context

#1092 stops the persisted cost estimate from leaking row-security bound values by dropping every plan node's detail (and raw_plan) whenever a row-security directive was applied. That is engine-agnostic and fail-closed, but reviewers lose all predicate / index-condition text on row-secured queries.

Proposal

Instead of dropping the text, scrub the bound values out of it before persistence in DefaultQueryCostEstimateService: replace every value from the resolved RowSecurityDirective.values() / rewrite binds with a marker such as <row-security> in each node's detail and in raw_plan.

Must handle engine-specific renderings: PostgreSQL quoting and casts ('x'::text, doubled ''), MySQL attached_condition, MongoDB extended JSON ({"$eq": "x"}, escaped quotes, numbers/dates), SQL++ / Cypher / Elasticsearch plan output.

Fail closed: after substitution, if any raw bound value (or its escaped form) is still found in a node's detail, drop that detail; if found in raw_plan, null it — i.e. degrade to the #1092 behaviour rather than risk a miss.

Acceptance

  • Per-engine unit tests covering quoting/escaping/casts, plus a PostgreSQL integration test asserting the bound value appears nowhere in the persisted or returned estimate while the redacted predicate shape is kept.
  • Non-RLS queries unchanged.
  • docs/05-backend.md → "Automatic pre-flight cost estimate" and docs/07-security.md updated.

Could be combined with the generic-plan approach (PostgreSQL) — redaction then covers the engines that have no generic-plan EXPLAIN.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions