diff --git a/docs/0001_unindexed_foreign_keys.md b/docs/0001_unindexed_foreign_keys.md index 8954802..7236efb 100644 --- a/docs/0001_unindexed_foreign_keys.md +++ b/docs/0001_unindexed_foreign_keys.md @@ -1,6 +1,11 @@ -Level: INFO +**Level:** INFO +**Summary:** Unindexed foreign keys + +**Ramification:** Database queries that filter or join on these columns will be slower because there is no index to speed them up. + +--- ### Rationale diff --git a/docs/0002_auth_users_exposed.md b/docs/0002_auth_users_exposed.md index e9a938b..5c9514e 100644 --- a/docs/0002_auth_users_exposed.md +++ b/docs/0002_auth_users_exposed.md @@ -1,5 +1,11 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** User data exposed through a view + +**Ramification:** A view is exposing your users' personal information to anyone who can access your API. + +--- ### Rationale diff --git a/docs/0003_auth_rls_initplan.md b/docs/0003_auth_rls_initplan.md index 2b0cf3b..3d09c8f 100644 --- a/docs/0003_auth_rls_initplan.md +++ b/docs/0003_auth_rls_initplan.md @@ -1,5 +1,11 @@ -Level: WARN +**Level:** WARN + +**Summary:** Slow security policy detected + +**Ramification:** A security policy is running its check on every single row instead of once per query, which slows down your database as your tables grow. + +--- ### Rationale diff --git a/docs/0004_no_primary_key.md b/docs/0004_no_primary_key.md index a5b2674..2106adb 100644 --- a/docs/0004_no_primary_key.md +++ b/docs/0004_no_primary_key.md @@ -1,5 +1,11 @@ -Level: INFO +**Level:** INFO + +**Summary:** Table has no primary key + +**Ramification:** Without a primary key, rows can't be uniquely identified, which can cause data issues and slower queries. + +--- ### Rationale diff --git a/docs/0005_unused_index.md b/docs/0005_unused_index.md index 89931e6..126c9b2 100644 --- a/docs/0005_unused_index.md +++ b/docs/0005_unused_index.md @@ -1,5 +1,11 @@ -Level: INFO +**Level:** INFO + +**Summary:** Unused index found + +**Ramification:** This index is never used by any query but still slows down every insert, update, and delete on the table. + +--- ### Rationale diff --git a/docs/0006_multiple_permissive_policies.md b/docs/0006_multiple_permissive_policies.md index 0d12ff4..cdc1ea8 100644 --- a/docs/0006_multiple_permissive_policies.md +++ b/docs/0006_multiple_permissive_policies.md @@ -1,5 +1,11 @@ -Level: WARN +**Level:** WARN + +**Summary:** Multiple permissive policies on a table + +**Ramification:** When several permissive policies exist on one table, access can become broader than intended and queries slower. + +--- ### Rationale diff --git a/docs/0007_policy_exists_rls_disabled.md b/docs/0007_policy_exists_rls_disabled.md index 38466b5..7201077 100644 --- a/docs/0007_policy_exists_rls_disabled.md +++ b/docs/0007_policy_exists_rls_disabled.md @@ -1,5 +1,11 @@ -Level: INFO +**Level:** INFO + +**Summary:** Security policy not enforced + +**Ramification:** A security policy exists but has no effect because Row-Level Security hasn't been turned on for the table. + +--- ### Rationale diff --git a/docs/0008_rls_enabled_no_policy.md b/docs/0008_rls_enabled_no_policy.md index 1b3b3fe..b597e2e 100644 --- a/docs/0008_rls_enabled_no_policy.md +++ b/docs/0008_rls_enabled_no_policy.md @@ -1,5 +1,11 @@ -Level: INFO +**Level:** INFO + +**Summary:** No access rules defined + +**Ramification:** Row-Level Security is enabled but no policies exist, so no data can be read or written through the API. + +--- ### Rationale diff --git a/docs/0009_duplicate_index.md b/docs/0009_duplicate_index.md index 257a1c0..2b0dadc 100644 --- a/docs/0009_duplicate_index.md +++ b/docs/0009_duplicate_index.md @@ -1,5 +1,11 @@ -Level: WARN +**Level:** WARN + +**Summary:** Duplicate index found + +**Ramification:** Identical indexes on the same table waste storage and slow down writes with no performance benefit. + +--- ### Rationale diff --git a/docs/0010_security_definer_view.md b/docs/0010_security_definer_view.md index 53888d3..0227f60 100644 --- a/docs/0010_security_definer_view.md +++ b/docs/0010_security_definer_view.md @@ -1,5 +1,11 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** View bypasses row-level security + +**Ramification:** A view in the public schema runs with elevated privileges and ignores Row-Level Security, which could expose more data through the API than intended. + +--- ### Rationale diff --git a/docs/0011_function_search_path_mutable.md b/docs/0011_function_search_path_mutable.md index 5d0cce7..30e388c 100644 --- a/docs/0011_function_search_path_mutable.md +++ b/docs/0011_function_search_path_mutable.md @@ -1,5 +1,11 @@ -Level: WARN +**Level:** WARN + +**Summary:** Unsecured function search path + +**Ramification:** Without a fixed search path, this function could behave unpredictably or be exploited to reference unintended database objects. + +--- ### Rationale diff --git a/docs/0012_auth_allow_anonymous_sign_ins.md b/docs/0012_auth_allow_anonymous_sign_ins.md index f83082b..905bb84 100644 --- a/docs/0012_auth_allow_anonymous_sign_ins.md +++ b/docs/0012_auth_allow_anonymous_sign_ins.md @@ -1,4 +1,10 @@ -Level: INFO +**Level:** INFO + +**Summary:** Anonymous sign-ins enabled + +**Ramification:** Anonymous users share the same database role as permanent users, so existing security policies may unintentionally grant them access. + +--- ### Rationale diff --git a/docs/0013_rls_disabled_in_public.md b/docs/0013_rls_disabled_in_public.md index 72b1e71..a56fef1 100644 --- a/docs/0013_rls_disabled_in_public.md +++ b/docs/0013_rls_disabled_in_public.md @@ -1,5 +1,11 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** Table publicly accessible + +**Ramification:** Anyone with your project URL can read, edit, and delete all data in this table because Row-Level Security is not enabled. + +--- ### Rationale diff --git a/docs/0014_extension_in_public.md b/docs/0014_extension_in_public.md index 55d1a54..9ed9253 100644 --- a/docs/0014_extension_in_public.md +++ b/docs/0014_extension_in_public.md @@ -1,5 +1,11 @@ -Level: WARN +**Level:** WARN + +**Summary:** Extension installed in public schema + +**Ramification:** The extension's internal functions and tables are visible in your API, cluttering it and potentially exposing unintended functionality. + +--- ### Rationale diff --git a/docs/0015_rls_references_user_metadata.md b/docs/0015_rls_references_user_metadata.md index d8bee7d..4404e8a 100644 --- a/docs/0015_rls_references_user_metadata.md +++ b/docs/0015_rls_references_user_metadata.md @@ -1,5 +1,11 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** Security policy relies on user-editable data + +**Ramification:** A security policy references user_metadata, which end users can freely modify, allowing them to bypass access controls. + +--- ### Rationale diff --git a/docs/0016_materialized_view_in_api.md b/docs/0016_materialized_view_in_api.md index 6d86bee..6eec286 100644 --- a/docs/0016_materialized_view_in_api.md +++ b/docs/0016_materialized_view_in_api.md @@ -1,4 +1,10 @@ -Level: WARN +**Level:** WARN + +**Summary:** Materialized view exposed in API + +**Ramification:** Materialized views can't be protected by Row-Level Security, so all their data is visible to every API user. + +--- ### Rationale diff --git a/docs/0017_foreign_table_in_api.md b/docs/0017_foreign_table_in_api.md index 56a1bd4..7fa8e41 100644 --- a/docs/0017_foreign_table_in_api.md +++ b/docs/0017_foreign_table_in_api.md @@ -1,4 +1,10 @@ -Level: WARN +**Level:** WARN + +**Summary:** Foreign table exposed in API + +**Ramification:** Foreign tables can't be protected by Row-Level Security, so all their data is visible to every API user. + +--- ### Rationale diff --git a/docs/0018_unsupported_reg_types.md b/docs/0018_unsupported_reg_types.md index 456dee9..31ce057 100644 --- a/docs/0018_unsupported_reg_types.md +++ b/docs/0018_unsupported_reg_types.md @@ -1,4 +1,10 @@ -Level: WARN +**Level:** WARN + +**Summary:** Column type blocks Postgres upgrades + +**Ramification:** A table uses a Postgres internal type that is not supported by pg_upgrade, which will prevent you from upgrading to future Postgres versions. + +--- ### Rationale diff --git a/docs/0019_insecure_queue_exposed_in_api.md b/docs/0019_insecure_queue_exposed_in_api.md index 4d7583f..0e31d46 100644 --- a/docs/0019_insecure_queue_exposed_in_api.md +++ b/docs/0019_insecure_queue_exposed_in_api.md @@ -1,5 +1,11 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** Queue exposed without protection + +**Ramification:** Anyone with your project URL can read, modify, and delete messages in this queue because it lacks access controls. + +--- ### Rationale diff --git a/docs/0020_table_bloat.md b/docs/0020_table_bloat.md index 667192e..18b8665 100644 --- a/docs/0020_table_bloat.md +++ b/docs/0020_table_bloat.md @@ -1,4 +1,10 @@ -Level: WARN +**Level:** WARN + +**Summary:** Excess table bloat detected + +**Ramification:** The table has accumulated significant unused space from old row versions, which increases storage costs and slows down queries. + +--- ### Rationale In PostgreSQL, bloat occurs when tables contain extra, unused space due to deleted or updated rows. PostgreSQL doesn’t immediately reclaim the space used by these rows but instead marks it as reusable for future operations. Over time, if this space isn’t efficiently reused, the table becomes bloated, meaning it takes up more storage than necessary, slowing down database performance and increasing I/O overhead. diff --git a/docs/0021_fkey_to_auth_unique.md b/docs/0021_fkey_to_auth_unique.md index 4d905e6..51cfec7 100644 --- a/docs/0021_fkey_to_auth_unique.md +++ b/docs/0021_fkey_to_auth_unique.md @@ -1,4 +1,10 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** Foreign key blocks Auth upgrades + +**Ramification:** A foreign key references a constraint in the auth schema that is scheduled for removal, which will prevent future Auth updates and security patches. + +--- ### Rationale diff --git a/docs/0022_extension_versions_outdated.md b/docs/0022_extension_versions_outdated.md index b1d3c62..f62f8a2 100644 --- a/docs/0022_extension_versions_outdated.md +++ b/docs/0022_extension_versions_outdated.md @@ -1,4 +1,10 @@ -Level: WARN +**Level:** WARN + +**Summary:** Extension out of date + +**Ramification:** An installed extension is running an older version that may be missing security patches and is not covered by the Supabase SLA. + +--- ### Rationale diff --git a/docs/0023_sensitive_columns_exposed.md b/docs/0023_sensitive_columns_exposed.md index 4eaed50..aefa05c 100644 --- a/docs/0023_sensitive_columns_exposed.md +++ b/docs/0023_sensitive_columns_exposed.md @@ -1,5 +1,11 @@ -Level: ERROR +**Level:** ERROR + +**Summary:** Sensitive data publicly accessible + +**Ramification:** A table with columns that likely contain sensitive data (like passwords or personal identifiers) is accessible through the API without any access restrictions. + +--- ### Rationale diff --git a/docs/0024_permissive_rls_policy.md b/docs/0024_permissive_rls_policy.md index 5ae699d..1422538 100644 --- a/docs/0024_permissive_rls_policy.md +++ b/docs/0024_permissive_rls_policy.md @@ -1,5 +1,11 @@ -Level: WARN +**Level:** WARN + +**Summary:** Security policy allows unrestricted access + +**Ramification:** An RLS policy uses an always-true condition like `USING (true)`, which defeats the purpose of having Row-Level Security enabled. + +--- ### Rationale diff --git a/mkdocs.yaml b/mkdocs.yaml index a60f2ba..b426929 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -19,9 +19,19 @@ nav: - Duplicate Index: '0009_duplicate_index.md' - Security Definer View: '0010_security_definer_view.md' - Function Search Path Mutable: '0011_function_search_path_mutable.md' + - Auth Allow Anonymous Sign-ins: '0012_auth_allow_anonymous_sign_ins.md' - RLS Disabled in Public: '0013_rls_disabled_in_public.md' - Extension in Public: '0014_extension_in_public.md' - RLS References user_metadata: '0015_rls_references_user_metadata.md' + - Materialized View in API: '0016_materialized_view_in_api.md' + - Foreign Table in API: '0017_foreign_table_in_api.md' + - Unsupported reg Types: '0018_unsupported_reg_types.md' + - Insecure Queue Exposed in API: '0019_insecure_queue_exposed_in_api.md' + - Table Bloat: '0020_table_bloat.md' + - Fkey to Auth Unique: '0021_fkey_to_auth_unique.md' + - Extension Versions Outdated: '0022_extension_versions_outdated.md' + - Sensitive Columns Exposed: '0023_sensitive_columns_exposed.md' + - Permissive RLS Policy: '0024_permissive_rls_policy.md' theme: name: 'material'