Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/installcheck
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ else
fi

# Execute the test fixtures
psql -v ON_ERROR_STOP= -f test/fixtures.sql -f lints/0001*.sql -f lints/0002*.sql -f lints/0003*.sql -f lints/0004*.sql -f lints/0005*.sql -f lints/0006*.sql -f lints/0007*.sql -f lints/0008*.sql -f lints/0009*.sql -f lints/0010*.sql -f lints/0011*.sql -f lints/0013*.sql -f lints/0014*.sql -f lints/0015*.sql -f lints/0016*.sql -f lints/0017*.sql -f lints/0018*.sql -f lints/0019*.sql -f lints/0020*.sql -f lints/0021*.sql -d contrib_regression
psql -v ON_ERROR_STOP= -f test/fixtures.sql -f lints/0001*.sql -f lints/0002*.sql -f lints/0003*.sql -f lints/0004*.sql -f lints/0005*.sql -f lints/0006*.sql -f lints/0007*.sql -f lints/0008*.sql -f lints/0009*.sql -f lints/0010*.sql -f lints/0011*.sql -f lints/0013*.sql -f lints/0014*.sql -f lints/0015*.sql -f lints/0016*.sql -f lints/0017*.sql -f lints/0018*.sql -f lints/0019*.sql -f lints/0020*.sql -f lints/0021*.sql -f lints/0022*.sql -d contrib_regression

# Run tests
${REGRESS} --use-existing --dbname=contrib_regression --inputdir=${TESTDIR} ${TESTS}
Expand Down
74 changes: 74 additions & 0 deletions docs/0022_extension_versions_outdated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Level: WARN

### Rationale

Keeping PostgreSQL extensions up to date is important for maintaining database security and stability. Extension developers regularly release updates that include:

- **Security patches** that fix known vulnerabilities
- **Bug fixes** that resolve functional issues
- **Performance improvements** that optimize database operations

Using outdated extension versions can expose your database to security risks and prevent you from benefiting from the latest improvements. Additionally, Supabase's Service Level Agreement (SLA) for issues resulting from extensions only applies to the default (recommended) version of each extension.

### Why Keep Extensions Updated?

**Security**: Outdated extensions may contain known security vulnerabilities that have been patched in newer versions. These vulnerabilities could potentially be exploited by malicious actors.

**Support**: Supabase provides support and SLA coverage only for the default (recommended) versions of extensions. Running outdated versions may result in limited support options if issues arise.

**Consistency**: Maintaining consistent extension versions across all projects helps ensure predictable behavior and reduces compatibility issues.

**Performance**: Newer versions frequently include performance optimizations and improvements that can benefit your database operations.

### Warning

- Always test extension updates in a development environment before applying them to production
- Some extension updates may include breaking changes, so review the extension's changelog before updating
- Back up your database before performing extension updates

### How to Resolve

To update an extension to its default (recommended) version, use the `ALTER EXTENSION` command:

```sql
ALTER EXTENSION extension_name UPDATE;
```

For example, to update the `uuid-ossp` extension:

First, check the version of the extension taht is installed:

```sql
-- Check current extension version
SELECT name, installed_version, default_version
FROM pg_available_extensions
WHERE name = 'uuid-ossp';
```

This could return:
```
name | installed_version | default_version
-------------+-------------------+-----------------
uuid-ossp | 1.0 | 1.1
```

To update to the installed version:

```sql
ALTER EXTENSION "uuid-ossp" UPDATE;
```

After updating, verify the installed version matches default:

```sql
SELECT name, installed_version, default_version
FROM pg_available_extensions
WHERE name = 'uuid-ossp';
```

Should now return:
```
name | installed_version | default_version
-------------+-------------------+-----------------
uuid-ossp | 1.1 | 1.1
```
34 changes: 34 additions & 0 deletions lints/0022_extension_versions_outdated.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
create view lint."0022_extension_versions_outdated" as

select
'extension_versions_outdated' as name,
'Extension Versions Outdated' as title,
'WARN' as level,
'EXTERNAL' as facing,
array['SECURITY'] as categories,
'Detects extensions that are not using the default (recommended) version.' as description,
format(
'Extension `%s` is using version `%s` but version `%s` is available. Using outdated extension versions may expose the database to security vulnerabilities.',
ext.name,
ext.installed_version,
ext.default_version
) as detail,
'https://supabase.com/docs/guides/database/database-linter?lint=0022_extension_versions_outdated' as remediation,
jsonb_build_object(
'extension_name', ext.name,
'installed_version', ext.installed_version,
'default_version', ext.default_version
) as metadata,
format(
'extension_versions_outdated_%s_%s',
ext.name,
ext.installed_version
) as cache_key
from
pg_catalog.pg_available_extensions ext
where
ext.installed_version is not null
and ext.default_version is not null
and ext.installed_version != ext.default_version
order by
ext.name;
36 changes: 35 additions & 1 deletion splinter.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1108,4 +1108,38 @@ from
where c.contype = 'f'
and cn.nspname = 'auth'
and i.indisunique
and not i.indisprimary)
and not i.indisprimary)
union all
(
select
'extension_versions_outdated' as name,
'Extension Versions Outdated' as title,
'WARN' as level,
'EXTERNAL' as facing,
array['SECURITY'] as categories,
'Detects extensions that are not using the default (recommended) version.' as description,
format(
'Extension `%s` is using version `%s` but version `%s` is available. Using outdated extension versions may expose the database to security vulnerabilities.',
ext.name,
ext.installed_version,
ext.default_version
) as detail,
'https://supabase.com/docs/guides/database/database-linter?lint=0022_extension_versions_outdated' as remediation,
jsonb_build_object(
'extension_name', ext.name,
'installed_version', ext.installed_version,
'default_version', ext.default_version
) as metadata,
format(
'extension_versions_outdated_%s_%s',
ext.name,
ext.installed_version
) as cache_key
from
pg_catalog.pg_available_extensions ext
where
ext.installed_version is not null
and ext.default_version is not null
and ext.installed_version != ext.default_version
order by
ext.name)
41 changes: 41 additions & 0 deletions test/expected/0022_extension_versions_outdated.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
begin;
-- 0 issues initially (all extensions should be up to date)
select * from lint."0022_extension_versions_outdated";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
------+-------+-------+--------+------------+-------------+--------+-------------+----------+-----------
(0 rows)

-- Note: We cannot easily create a test that shows outdated extensions
-- because we cannot install older versions of extensions in a test environment.
-- Our test image doesn't have multiple extension versions available.
-- The test will primarily verify that the query executes without error
-- and returns the expected column structure.
-- This lint was tested manually with real outdated extensions.
-- Verify the query structure and column names
select
count(*) as total_outdated_extensions
from lint."0022_extension_versions_outdated";
total_outdated_extensions
---------------------------
0
(1 row)

-- Test that the query returns proper column structure
-- This will help ensure the lint is properly formed
select
name,
title,
level,
facing,
categories,
description,
detail,
remediation,
metadata,
cache_key
from lint."0022_extension_versions_outdated";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
------+-------+-------+--------+------------+-------------+--------+-------------+----------+-----------
(0 rows)

rollback;
6 changes: 5 additions & 1 deletion test/expected/queries_are_unionable.out
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ begin;
union all
select * from lint."0019_insecure_queue_exposed_in_api"
union all
select * from lint."0020_table_bloat";
select * from lint."0020_table_bloat"
union all
select * from lint."0021_fkey_to_auth_unique"
union all
select * from lint."0022_extension_versions_outdated";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
------+-------+-------+--------+------------+-------------+--------+-------------+----------+-----------
(0 rows)
Expand Down
33 changes: 33 additions & 0 deletions test/sql/0022_extension_versions_outdated.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
begin;

-- 0 issues initially (all extensions should be up to date)
select * from lint."0022_extension_versions_outdated";

-- Note: We cannot easily create a test that shows outdated extensions
-- because we cannot install older versions of extensions in a test environment.
-- Our test image doesn't have multiple extension versions available.
-- The test will primarily verify that the query executes without error
-- and returns the expected column structure.
-- This lint was tested manually with real outdated extensions.

-- Verify the query structure and column names
select
count(*) as total_outdated_extensions
from lint."0022_extension_versions_outdated";

-- Test that the query returns proper column structure
-- This will help ensure the lint is properly formed
select
name,
title,
level,
facing,
categories,
description,
detail,
remediation,
metadata,
cache_key
from lint."0022_extension_versions_outdated";

rollback;
6 changes: 5 additions & 1 deletion test/sql/queries_are_unionable.sql
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ begin;
union all
select * from lint."0019_insecure_queue_exposed_in_api"
union all
select * from lint."0020_table_bloat";
select * from lint."0020_table_bloat"
union all
select * from lint."0021_fkey_to_auth_unique"
union all
select * from lint."0022_extension_versions_outdated";

rollback;