Generate a CVE catalog + Supabase impact analysis for a PostgreSQL security release. Use when reviewing a new upstream PG quarterly security release to decide what to ship and how to communicate. Inputs are the version ranges (e.g. REL_15_14..REL_15_18 + REL_17_6..REL_17_10); output is a draft catalog markdown ready to post on the breaking-change-analysis Linear ticket.
npx skills add https://github.com/supabase/postgres --skill pg-security-release-analysis
You help the Supabase Postgres team analyze upstream PG security releases. The goal is to convert "PG just shipped a new minor security release" into a complete, verifiable catalog of (a) every customer-affecting change (CVE and non-CVE), (b) the Supabase surface area it touches, and (c) what we need to communicate. Worked example: PSQL-1110 (May 2026 cycle).
If not provided, ask the user for the upstream PG version ranges to analyze. Typically:
pg15_from..pg15_to (e.g. REL_15_14..REL_15_18)pg17_from..pg17_to (e.g. REL_17_6..REL_17_10)For each branch, the from version is what's currently in nix/config.nix; the to version is the target.
git log --grep does not tell you "first landed in version X." Use git tag --contains <sha> | grep -E '^REL_(15|17)_' | sort -V | head -1.https://www.postgresql.org/support/security/. The May 2026 cycle had 5 misclassified severities on first pass.--grep=CVE alone misses everything that wasn't tagged with a CVE. The Pattern Matrix below is mandatory — walk it in full, every cycle, regardless of CVE count.Cache at /tmp/postgres-upstream so subsequent runs reuse it.
if [ ! -d /tmp/postgres-upstream ]; then
git clone --filter=blob:none --no-checkout https://github.com/postgres/postgres.git /tmp/postgres-upstream
fi
git -C /tmp/postgres-upstream fetch --depth=600 origin \
refs/tags/<pg15_from>:refs/tags/<pg15_from> \
refs/tags/<pg15_to>:refs/tags/<pg15_to> \
refs/tags/<pg17_from>:refs/tags/<pg17_from> \
refs/tags/<pg17_to>:refs/tags/<pg17_to>
Verify: git -C /tmp/postgres-upstream tag --list 'REL_1[57]_*' | sort -V.
git -C /tmp/postgres-upstream log <pg15_from>..<pg15_to> --format=%B | grep -oE 'CVE-[0-9]{4}-[0-9]+' | sort -u
git -C /tmp/postgres-upstream log <pg17_from>..<pg17_to> --format=%B | grep -oE 'CVE-[0-9]{4}-[0-9]+' | sort -u
For each CVE in either list, run git log <range> --grep='CVE-XXXX-YYYY' --format='%h %s' and confirm at least one commit is a real fix (subject line is not "Last-minute updates for release notes").
Fetch https://www.postgresql.org/support/security/. For every in-scope CVE, capture:
For each in-scope CVE:
git -C /tmp/postgres-upstream log <range> --grep='CVE-XXXX-YYYY' --format='%h %s'
git -C /tmp/postgres-upstream tag --contains <fix-sha> | grep -E '^REL_(15|17)_' | sort -V | head -1
For every release, walk through the matrix below. For each class, run the detection command, read what comes back, and answer the Supabase-impact question. Do NOT skip classes that "feel unlikely" — the whole point is to catch the surprise.
(Matrix is its own section below — see Pattern Matrix.)
For every finding from Step 5, ask: which piece of the Supabase Surface Map does it touch? If none, the risk is bounded. If one or more, document the customer-impact path explicitly.
(Surface map is its own section below — see Supabase Surface Map.)
Output a markdown catalog matching PSQL-1110's comment structure. Sections:
#, CVE, Severity (CVSS), First landed in, Affected component, Upstream fix (15.x) (linked sha), Upstream fix (17.x) (linked sha), Supabase impact, Mitigation / actionCommit-link format: <8-char-sha>.
Walk every class for every release. Detection commands assume git -C /tmp/postgres-upstream and <range> = the version range (e.g. REL_15_14..REL_15_18).
What it looks like: new superuser() checks, new pg_*_aclcheck / object_aclcheck calls, default role privilege changes.
Detection:
git log <range> --oneline -- src/backend/commands/ src/backend/catalog/ | grep -iE 'privilege|aclcheck|superuser'
git log <range> -p -- src/backend/commands/ | grep -nE '^\+.*\b(superuser\(\)|pg_proc_aclcheck|object_aclcheck)' | head -40
Supabase impact questions: Customer roles (postgres, anon, authenticated, service_role, supabase_admin_lite) are non-superuser. Which of the new checks do they trip? Does the trip happen at runtime, at dump/restore time, or at pg_upgrade? Are any default-installed extensions affected?
Historical example: CVE-2026-2004 (May 2026) — superuser required for non-built-in selectivity estimators on operators. Fired at pg_dump / pg_restore / pg_upgrade time, not runtime.
What it looks like: multibyte / locale / collation / case-folding fixes, comparison function fixes, index correctness fixes (GiST / GIN / B-tree / BRIN). Failures are typically SILENT — wrong query results, not errors.
Detection:
git log <range> --oneline -- src/backend/utils/ src/backend/access/ contrib/ | grep -iE 'multibyte|collation|locale|case[- ]?fold|comparison|overflow|truncat'
git log <range> --oneline -- contrib/ | grep -iE 'fix|wrong|incorrect' | grep -viE 'test|comment|typo|docs?|format'
Supabase impact questions: Does this require REINDEX on existing indexes? Which encodings / collation providers (libc vs ICU) are affected? Which Supabase-shipped extensions touch this code path? Is the failure mode silent (wrong results) or noisy (error)? If silent, it warrants headline customer comms.
Historical example: ltree multibyte case-folding fix (May 2026 cycle) — required REINDEX on UTF-8 / ICU databases; ~2,245 projects affected.
What it looks like: palloc / alloc overflow fixes, bounds-check additions, length validation in parsers.
Detection:
git log <range> --oneline | grep -iE 'overflow|palloc|bound|overrun|MaxAllocSize|integer overflow'
git log <range> --oneline -- src/backend/utils/mb/ src/backend/utils/adt/ | grep -iE 'overflow|length'
Supabase impact questions: Was the bug exploitable by an authenticated customer with crafted input? Does the affected code path get exercised by default-shipped extensions (pgcrypto, pg_trgm, intarray, ltree) or RLS-policy expressions?
What it looks like: fixes in pg_dump output formatting, dynamic SQL inside contrib modules, identifier quoting bugs.
Detection:
git log <range> --oneline | grep -iE 'quot|escape|inject|sql.+inject'
git log <range> --oneline -- src/bin/pg_dump/ contrib/ | grep -iE 'quot|escape'
Supabase impact questions: Does the affected tool (pg_dump, pg_restore, or a contrib module) run with elevated privileges in any Supabase flow (logical backup, project clone, wal-g)? Are customer-supplied identifiers (table names, role names) ever interpolated unsafely?
Historical example: CVE-2026-6637 (May 2026) — refint check_foreign_key() SQL injection. refint not default-enabled at Supabase but available via CREATE EXTENSION.
What it looks like: bug fixes in pg_basebackup, pg_rewind, pg_dump, pg_restore, pg_upgrade, pg_createsubscriber, pg_verifybackup, pg_combinebackup, libpq, psql, ecpg.
Detection:
git log <range> --oneline -- src/bin/ src/interfaces/libpq/
Supabase impact questions: Which Supabase services use this binary?
pg_basebackup → wal-g PITR pipelinelibpq → bundled in AMI, used by psql / pgbouncer / PostgREST / GoTrue connection pathspg_dump / pg_restore → dashboard "Clone Project" flow, logical backupspg_upgrade → dashboard version-upgrade flowpg_createsubscriber → grep supabase/postgres for usage; PG 17+ onlyFor each binary, also check: does Supabase pin the version, or does it pick up whatever ships with the new minor?
Historical example: CVE-2026-6475 (May 2026) — pg_basebackup / pg_rewind path traversal. wal-g uses pg_basebackup (verified in ansible/tasks/setup-wal-g.yml).
What it looks like: changes to struct layouts, enum value ordering, function signatures, or header definitions in src/include/.
Detection:
git log <range> --oneline -- src/include/ | head -40
git diff <pg17_from>..<pg17_to> -- src/include/ | grep -E '^-[^-].*\b(struct|enum|typedef|extern)' | head -40
git log <range> --oneline | grep -iE 'ABI|API|signature|enum.+order'
Supabase impact questions: All extensions in nix/ext/ rebuild from source via nix, so internal ABI shifts don't affect them. But: customer-supplied / non-nix-built C extensions could break. Is any third-party C extension whitelisted today?
Historical example: ProcSignalReason enum ordering restored in PG 17.x (commit 586f4266) — would have broken any C extension that read enum values out of position.
What it looks like: planner optimization fixes, statistics gathering changes, selectivity estimator updates, cost-estimation fixes, memoization fixes.
Detection:
git log <range> --oneline -- src/backend/optimizer/ src/backend/utils/adt/selfuncs.c src/backend/statistics/ | head -40
git log <range> --oneline -- contrib/ | grep -iE 'selectivity|estimate|stat|plan'
Supabase impact questions: Could query plans shift for existing customers? Are statistics rebuild (ANALYZE) or REINDEX required for the fix to take effect? Are there cost regressions on common Supabase query shapes (RLS-heavy, JSON path expressions, full-text search)?
Historical example: c89510431a (May 2026) — intarray selectivity estimation overflow near INT_MAX. Wrong plans for intarray-heavy workloads.
What it looks like: changes to default GUC values, postgresql.conf.sample, parameter renames, deprecations.
Detection:
git log <range> --oneline -- src/backend/utils/misc/postgresql.conf.sample src/backend/utils/misc/guc_tables.c
git diff <range> -- src/backend/utils/misc/postgresql.conf.sample | head -100
git log <range> --oneline | grep -iE 'default.+value|GUC|setting'
Supabase impact questions: Does Supabase already override this GUC in ansible/files/postgresql_config/postgresql.conf.j2? If not, does the new default affect anything customers depend on (logging verbosity, timeouts, connection limits, replication, SSL params)?
What it looks like: walsender / walreceiver fixes, logical replication (subscriptions, publications, slotsync), WAL format changes, recovery / checkpoint fixes, FSM/VM persistence.
Detection:
git log <range> --oneline -- src/backend/replication/ src/backend/access/transam/ | head -40
git log <range> --oneline | grep -iE 'walsender|walreceiver|slotsync|publication|subscription|recovery|checkpoint|WAL'
Supabase impact questions:
pgoutput decoder + publications). Any change to publication catalog, REFRESH PUBLICATION, or decoding behavior?Historical example: PG 17.10 fixed walsender shutdown hang, slotsync workers blocking standby promotion. Both affect production-cluster behavior.
What it looks like: SCRAM / GSS / SSL handshake fixes, certificate handling, password hashing (MD5, SCRAM-SHA-256), timing-safe comparisons.
Detection:
git log <range> --oneline -- src/backend/libpq/ src/backend/utils/adt/cryptohashes.c | head -40
git log <range> --oneline | grep -iE 'SCRAM|GSS|SSL|TLS|password|hash|cert|auth'
Supabase impact questions: Default auth method on Supabase is SCRAM-SHA-256 (verify in ansible/files/postgresql_config/postgresql.conf.j2 or pg_hba.conf). Are legacy MD5 users still present in any tier? Does the change affect pgbouncer's auth pass-through?
Historical example: CVE-2026-6478 (May 2026) — timing-unsafe MD5 password comparison. Affects legacy MD5-auth users.
What it looks like: any commit under contrib/<name>/ for extensions Supabase preloads or default-installs, OR any of the Supabase-shipped extensions in nix/ext/ getting upstream updates.
Detection:
# Look at every contrib extension we ship
for ext in pgcrypto pg_stat_statements pgaudit pg_cron pg_net pgsodium pg_graphql pg_tle plan_filter supabase_vault auto_explain plpgsql plpgsql_check timescaledb intarray ltree hstore citext refint xml2 amcheck pgvector pg_trgm postgres_fdw; do
count=$(git log <range> --oneline -- contrib/$ext/ 2>/dev/null | wc -l)
if [ "$count" -gt 0 ]; then echo "$ext: $count commits"; fi
done
Supabase impact questions: For each affected extension, is it (a) preloaded via shared_preload_libraries, (b) auto-created in migrations/db/init-scripts/, or (c) merely available via CREATE EXTENSION? The first two affect every project; the third only affects opt-in customers.
Inventory of what to cross-check Pattern Matrix findings against. Update this map when surface area changes.
From migrations/db/init-scripts/00000000000000-initial-schema.sql: pgcrypto, uuid-ossp, pg_stat_statements, supabase_vault.
shared_preload_libraries (worker extensions preloaded into every postmaster)From ansible/files/postgresql_config/postgresql.conf.j2:
pg_stat_statements, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, pg_tle, plan_filter, supabase_vault.
nix/ext/, opt-in via CREATE EXTENSION)Run ls nix/ext/ for the current list. Includes (non-exhaustive): pgvector, pgroonga, pgrouting, postgis, pgtap, pgjwt, hypopg, index_advisor, pg_hashids, pg_jsonschema, pg_partman, pg_repack, pg_safeupdate, pg_stat_monitor, pgmq, pljava, plv8, pg_backtrace.
postgres, anon, authenticated, service_role, supabase_admin_lite. Note: in older clusters, postgres had elevated privileges; verify role definitions in migrations/db/init-scripts/.
supabase_admin (superuser), supabase_storage_admin, supabase_auth_admin, supabase_replication_admin, supabase_functions_admin.
pg_basebackup. Setup in ansible/tasks/setup-wal-g.yml.psql (bundled in AMI), pgbouncer (connection pooling), PostgREST, GoTrue, Realtime (logical replication consumer).
nix/ext/); runtime config in supautils.conf, often overridden by salt.docker/Dockerfile-15 and Dockerfile-17 for local dev; libpq version bundled too.git tag --contains; cross-check severity against the security page; cross-check every finding against the Supabase Surface Map./tmp/postgres-upstream).--grep=CVE alone.FirstGenbkiObjectId threshold: src/include/access/transam.h (= 10000, used by upstream privilege gates)playbooks/product-ops/how-to-do-breaking-changes.mdplaybooks/infra/running-minor-major-postgres-version-updates-for-platform-images.mdBuild production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
Use when building Laravel 10+ applications requiring Eloquent ORM, API resources, or queue systems. Invoke for Laravel models, Livewire components, Sanctum authentication, Horizon queues.
Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting. But the ease of setup hides real complexity. Security rules are your last line of defense, and they're often wrong. Firestore queries are limited, and you learn this after you've designed your data model. This skill covers Firebase Authentication, Firestore, Realtime Database, Cloud Functions, Cloud Storage, and Firebase Hosting. Key insight: Firebase is optimized for read-heavy, denormalized data. I
Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
Use when building, configuring, or debugging enterprise Java applications with Spring Boot 3.x, microservices, or reactive programming. Invoke to implement WebFlux endpoints, optimize JPA queries and database performance, configure Spring Security with OAuth2/JWT, or resolve authentication issues and async processing challenges in cloud-native Spring applications.
This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing." It provides comprehensive guidance for using SQLMap to detect and exploit SQL injection vulnerabilities.
Connects MATLAB to Databricks using JDBC drivers via Database Toolbox. Use when creating a JDBC connection to a Databricks cluster or SQL Warehouse, configuring Databricks authentication (PAT, OauthU2M, OauthM2M), selecting between Simba and OSS JDBC drivers, using databricks.JDBCConnection, StandaloneJDBCConnection, databricks.SQLWarehouse.connect(), or optimizing Databricks write performance.
Take supabase/pg-security-release-analysis from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.