Commit Graph

3 Commits

Author SHA1 Message Date
Charis 9bdb757b6a feat(logs): brand Observability/EdgeFunctions SQL with SafeLogSqlFragment (#8) (#46466)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Refactor / security hardening — continues the analytics SQL
provenance-tracking series (PR 8).

## What is the current behavior?

- `generateRegexpWhere` (unsafe: interpolates user-controlled filter
keys/values without escaping) still exists alongside
`generateRegexpWhereSafe` and its tests only cover the old function.
- `usePostgrestOverviewMetrics` builds a SQL query string with plain
string interpolation and calls the analytics endpoint directly via
`get()`.
- `edge-functions-last-hour-stats-query` builds a SQL query with
`functionIds` escaped via Postgres-only `quoteLiteral` and calls the
analytics endpoint directly via `post()`.
- `executeAnalyticsSql` has no way to pass a `key` query-string param
for network-tool identification.
- `rawSql('minute')` / `rawSql('hour')` / `rawSql('day')` and
`rawSql(value ? 'true' : 'false')` are used for static strings that
could be expressed with the `safeSql` template tag.

## What is the new behavior?

- `generateRegexpWhere` is deleted; its tests are replaced with
`generateRegexpWhereSafe` coverage including injection-attempt cases
(`level OR id IS NOT NULL`, `request.method); DROP TABLE edge_logs; --`)
that verify predicates are silently dropped rather than emitted.
- `usePostgrestOverviewMetrics` returns `SafeLogSqlFragment` from its
SQL builder and routes through `executeAnalyticsSql`.
- `edge-functions-last-hour-stats-query` uses `analyticsLiteral`
(BigQuery/ClickHouse-correct escaping) instead of `quoteLiteral`
(Postgres-only) and routes through `executeAnalyticsSql`.
- `executeAnalyticsSql` accepts an optional `key?: string` forwarded as
a query-string param on both GET and POST requests; `key:
'last-hour-stats'` is restored on the edge-functions query.
- Static `rawSql('...')` calls replaced with `safeSql\`...\`` template
literals throughout.

## Additional context

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Bug Fixes
- Removed legacy unsafe SQL-filter utility from Reports

## Chores
- Enhanced analytics SQL execution infrastructure with improved error
handling
- Added optional request identification parameter to analytics query
execution
- Refined SQL filtering mechanisms in reporting features

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46466?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-28 10:30:57 -04:00
Charis a7d51cdf52 feat(logs): brand legacy analytics SQL stack with SafeLogSqlFragment (#46351)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Refactor / type safety improvement

## What is the current behavior?

The legacy log query stack (`genDefaultQuery`, `genCountQuery`,
`genChartQuery`, `genWhereStatement`, `useLogsPreview`, `useSingleLog`)
builds SQL from raw strings with no type-level guarantee that values are
safely interpolated. Identifier helpers (`bqIdent`, `bqDottedIdent`,
`clickhouseIdent`, `clickhouseDottedIdent`) are duplicated across
BigQuery and ClickHouse variants, and `bqDottedIdent` wraps the entire
dotted path in one backtick pair (`` `request.pathname` ``), which
BigQuery treats as a literal column name rather than a UNNEST alias
field — causing runtime query failures on dotted filter keys.

## What is the new behavior?

- All gen functions return `SafeLogSqlFragment` and all callers route
through `executeAnalyticsSql`, enforcing compile-time SQL provenance
tracking across the legacy stack.
- `bqIdent` / `bqDottedIdent` / `clickhouseIdent` /
`clickhouseDottedIdent` are replaced by a single `quotedIdent` function
that backtick-quotes each segment individually (e.g. ``
`request`.`pathname` ``). ClickHouse natively accepts backticks, so one
function serves both engines and the dotted-path quoting bug is fixed.
- `SQL_FILTER_TEMPLATES` entries are converted to `SafeLogSqlFragment`
(static via `safeSql`, dynamic via `safeSql` + `analyticsLiteral`).
- `buildWhereClauses` is extracted as a private helper returning
`SafeLogSqlFragment[]` so the pg_cron path can merge clauses without
unsafe slice-and-cast.

## Additional context

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Logs query generation migrated to safer, engine-agnostic SQL
fragments, typed filter templates, and unified identifier quoting for
stronger injection protection and more consistent queries.
* Logs preview and single-log retrieval now execute analytics SQL
end-to-end using the unified executor.

* **New Features**
* Analytics SQL executor can call the backend via GET or POST and
accepts method selection.

* **Tests**
* Updated tests to validate unified identifier quoting and safe-SQL
helper behavior.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46351?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-26 15:20:54 -04:00
Charis d117e70f6c feat: add safe SQL execution for analytics queries (BigQuery/ClickHouse) (#46287)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Feature - Security infrastructure

## What is the current behavior?

Analytics queries (BigQuery for legacy cloud, ClickHouse for self-hosted
OTEL) lack a compile-time safety model to prevent SQL injection from
untrusted input sources like URL parameters, UI inputs, or LLM output.

## What is the new behavior?

Implement a security model with a branded type `SafeLogSqlFragment` that
ensures all SQL fragments originate from either static code or
sanitization helpers. This includes:

- `analyticsLiteral()` for escaping string/number/boolean values
- `bqIdent()` and `clickhouseIdent()` for quoting identifiers with
engine-specific syntax
- `safeSql` template tag for composing fragments safely
- `executeAnalyticsSql()` wire boundary that rejects plain strings at
compile time

The pattern prevents cross-engine confusion by keeping
`SafeLogSqlFragment` (analytics) distinct from pg-meta's
`SafeSqlFragment` (Postgres).

## Additional context

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced analytics SQL execution capabilities with built-in safety
validation for queries.
* Enhanced query robustness through keyword and identifier validation
mechanisms.
  * Improved error handling and reporting for analytics operations.

* **Tests**
* Added comprehensive test suite for analytics SQL safety and validation
utilities.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46287?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-25 08:40:18 -04:00