mirror of
https://github.com/supabase/supabase.git
synced 2026-10-09 19:35:06 +03:00
## 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 --> [](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 -->
51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
/**
|
|
* Wire-boundary for analytics SQL execution.
|
|
*
|
|
* This is the analytics-path analog of pg-meta's `executeSql`. It accepts only
|
|
* `SafeLogSqlFragment` — plain strings are rejected at compile time — so any
|
|
* value flowing from URL parameters, UI inputs, or LLM output must pass through
|
|
* a sanitization helper in safe-analytics-sql.ts before reaching the wire.
|
|
*
|
|
* See .claude/skills/safe-sql-execution/SKILL.md for the full security model.
|
|
*/
|
|
import type { SafeLogSqlFragment } from './safe-analytics-sql'
|
|
import { handleError, post } from '@/data/fetchers'
|
|
|
|
/**
|
|
* Analytics endpoints that accept a POST body with `{ sql, iso_timestamp_start, iso_timestamp_end }`.
|
|
* Extend this union as additional endpoints are migrated to the safe-analytics-sql pattern.
|
|
*/
|
|
export type AnalyticsSqlEndpoint =
|
|
| '/platform/projects/{ref}/analytics/endpoints/logs.all'
|
|
| '/platform/projects/{ref}/analytics/endpoints/logs.all.otel'
|
|
|
|
export interface ExecuteAnalyticsSqlVariables {
|
|
projectRef: string
|
|
endpoint: AnalyticsSqlEndpoint
|
|
/** Must carry the `SafeLogSqlFragment` brand — plain strings are rejected at compile time. */
|
|
sql: SafeLogSqlFragment
|
|
iso_timestamp_start: string
|
|
iso_timestamp_end: string
|
|
signal?: AbortSignal
|
|
headers?: HeadersInit
|
|
}
|
|
|
|
export async function executeAnalyticsSql({
|
|
projectRef,
|
|
endpoint,
|
|
sql,
|
|
iso_timestamp_start,
|
|
iso_timestamp_end,
|
|
signal,
|
|
headers: headersInit,
|
|
}: ExecuteAnalyticsSqlVariables) {
|
|
const { data, error } = await post(endpoint, {
|
|
params: { path: { ref: projectRef } },
|
|
body: { sql, iso_timestamp_start, iso_timestamp_end },
|
|
signal,
|
|
headers: headersInit !== undefined ? new Headers(headersInit) : undefined,
|
|
})
|
|
if (error) handleError(error)
|
|
return data
|
|
}
|