Skip to content

Supabase's October 30 change: new public tables need a grant for Data API access. What to doSupabase's October 30 change is live: new public tables need a grant for Data API access. What broke and how to fix it

24 tools · 139 fixes · 42 issue guides · Sources: Supabase, GitHub, postgresql.org, Vercel + 53

Incident feed

Supabase Storage accepted a signed JWT with role none and bypassed RLS

On November 6, 2026, Supabase published GHSA-fgvp-cqg6-q8h2 for Supabase Storage 1.89.8 and earlier. Exploitation requires a trusted token issuer, for example a custom access-token hook, to emit a valid signed JWT containing role: "none". A request authenticated with that token could run database operations as the Storage database connection user and bypass row-level security when that user owns the Storage tables and row-level security is not forced on the owner. That could allow unauthorized reads from private buckets, object uploads, and bucket creation. The advisory rates it Critical, CVSS 3.1 score 9.8, lists 1.89.9 as the fix, and says the hosted platform is already patched.

Share link · Share on X

What was reported

GHSA-fgvp-cqg6-q8h2, published November 6, 2026, says exploitation requires a trusted token issuer to emit a valid signed JWT containing role: "none", for example through a custom access-token hook. In Supabase Storage, a request authenticated with that token could run database operations as the Storage database connection user. When that user owns the Storage tables and row-level security is not forced on the owner, those operations bypass row-level security policies. The advisory says that could allow unauthorized reads from private buckets, object uploads, and bucket creation within an affected project.

Prerequisites and impact

Exploitation requires a trusted token issuer to issue a token that contains this role, for example through a custom access-token hook. The advisory says modifying the role in an existing token without a valid signature does not enable the bypass.

Storage verifies the JWT signature and uses the token role claim to set the database authorization context. It passes the value to PostgreSQL through the parameterized call set_config('role', $1, true). PostgreSQL gives the exact value none special meaning: it resets the effective database role to the session user. Where Storage connects as supabase_storage_admin, that user owns the Storage tables. Table ownership exempts it from RLS unless FORCE ROW LEVEL SECURITY is enabled. The advisory says superuser privileges or the BYPASSRLS attribute are not required for this owner exemption. Request logs can still show role: none and the caller user ID because those fields come from JWT claims rather than the PostgreSQL effective role. An arbitrary nonexistent role is rejected by PostgreSQL. Empty or missing role claims fall back to anon.

The advisory rates the issue Critical, CVSS 3.1 score 9.8, vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, assigns CWE-270, Privilege Context Switching Error, and CWE-863, Incorrect Authorization, and lists no CVE id. The advisory's version data lists <= 1.89.8 as affected and 1.89.9 as patched. It does not name an npm package in that version data.

Fixed versions

Upgrade to 1.89.9 or later. The advisory says the hosted platform is already patched. The fix rejects none before applying the database authorization context and returns AccessDenied, and it preserves legitimate service_role access and custom database roles.

If upgrading a self-hosted instance is not immediately possible, the advisory says to correct any custom access-token hook or other trusted token issuer that emits role: "none" and to use an existing database role with the intended permissions. Changing token issuance alone does not neutralize previously issued tokens. Until the fix is deployed, it says to enforce rejection of role: "none" across all exposed Storage entry points or restrict access to the affected service until those tokens expire, and that any gateway mitigation must also prevent direct access to an unprotected Storage origin.

Our advice, not the advisory's: if you also self-host Storage at or below 1.89.9 for other reasons, check GHSA-3m3f-pjv4-x2fp separately. That advisory still lists 1.89.10 as the fix for a different issue (presigned PUT to cross-bucket read). This item's fix version remains 1.89.9.

How to prevent it

If you self-host Supabase Storage, upgrade to 1.89.9 or later. Until you upgrade, stop any custom access-token hook or other trusted issuer from emitting role: "none". Changing token issuance alone does not neutralize tokens already issued with that role, so also reject role: "none" at every exposed Storage entry point, including direct access to the Storage origin, or restrict access to the affected service until those tokens expire. The advisory says the hosted platform is already patched.

Sources

Related

The weekly fix

The weekly fix: 3 real security mistakes in vibe-coded apps and how to fix them, every Tuesday.

One email, every Tuesday. A welcome note follows the first signup.