mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
docs: add pgcrypto legacy-cipher caveat for the 15.19/17.11 upgrade (#49894)
## 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? Docs update — follow-up to #49621 for the Postgres 15.19 / 17.11 release. ## What is the current behavior? The upgrade guide covers three of the four customer-action items for this release; the pgcrypto legacy-cipher caveat (CVE-2026-14663) was deliberately held pending Security sign-off on the wording. ## What is the new behavior? Adds a "Pgcrypto legacy PGP ciphers" section (between the Ltree and Btree_gist sections, matching the release comms order): who is affected (`bf`/`blowfish`/`cast5` only), the wrong-key decrypt probe to check stored data, the AES re-encrypt step (with `ignore-cipher-failure=1` for post-upgrade recovery), and the secret-rotation recommendation. Wording approved by Security. ## Additional context Refs PSQL-1245 / PSQL-1110. Matches the customer email draft and changelog entry wording. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Updated `pgcrypto` upgrade guidance to separate pre-upgrade decryption from post-upgrade recovery, including the appropriate handling for cipher failures. - Added row-based targeting and plaintext spot checks before bulk updates. - Clarified that automated wrong-key scans cover symmetric messages; public-key messages require manual identification and key-pair re-encryption. - Updated the caution note to direct users to scan stored values rather than rely on a fixed list of cipher algorithms. No action is needed when `cipher-algo` was never specified. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
d5e8c882c1
commit
3d2148a821
2 files changed
+57
No files matched your search
@@ -286,6 +286,61 @@ Reindex each index it returns, using the schema-qualified name. `REINDEX INDEX C
|
||||
REINDEX INDEX CONCURRENTLY <schema_name>.<index_name>;
|
||||
```
|
||||
|
||||
### Pgcrypto legacy PGP ciphers
|
||||
|
||||
_Applies when upgrading to Postgres 15.19 or 17.11._
|
||||
|
||||
<Admonition type="caution">
|
||||
|
||||
You are affected only if you call pgcrypto PGP functions with a `cipher-algo` that is unavailable in your server's OpenSSL build. The default cipher (AES) is not affected — if you never pass a `cipher-algo` option, no action is needed. Use the scan below to check stored values.
|
||||
|
||||
</Admonition>
|
||||
|
||||
This release fixes [CVE-2026-14663](https://www.postgresql.org/support/security/CVE-2026-14663/): previously, when a requested PGP cipher was unavailable in the server's OpenSSL build, pgcrypto did not apply it, so affected values were not protected as intended and can be decrypted even with the wrong key. After upgrading, decrypting such messages fails by default, and encrypting with those ciphers returns an error.
|
||||
|
||||
To find affected rows, scan each stored value with a deliberately wrong passphrase: properly encrypted values raise an error, while affected values decrypt successfully even with the wrong key. Run the helper and the scan in the same session (`pg_temp` functions are session-scoped):
|
||||
|
||||
```sql
|
||||
create function pg_temp.affected_by_cve_2026_14663(msg bytea)
|
||||
returns boolean
|
||||
language plpgsql as $$
|
||||
begin
|
||||
perform pgp_sym_decrypt_bytea(msg, 'deliberately-wrong-key');
|
||||
return true;
|
||||
exception when others then
|
||||
return false;
|
||||
end $$;
|
||||
|
||||
select <id_column>
|
||||
from <your_table>
|
||||
where <your_encrypted_column> is not null
|
||||
and pg_temp.affected_by_cve_2026_14663(<your_encrypted_column>);
|
||||
```
|
||||
|
||||
Any rows returned hold affected values. The scan covers symmetric (`pgp_sym_*`) messages; the wrong-key probe does not apply to public-key (`pgp_pub_*`) messages. If you call `pgp_pub_encrypt` with one of the affected `cipher-algo` options, treat those values as affected and re-encrypt them the same way using `pgp_pub_decrypt` and `pgp_pub_encrypt` with your key pair.
|
||||
|
||||
Re-encrypt affected values with a modern cipher. Before you upgrade, the current version still decrypts them normally:
|
||||
|
||||
```sql
|
||||
update <your_table>
|
||||
set <col> = pgp_sym_encrypt(
|
||||
pgp_sym_decrypt(<col>, '<your-key>'),
|
||||
'<your-key>', 'cipher-algo=aes256')
|
||||
where <id_column> in (/* rows found by the scan above */);
|
||||
```
|
||||
|
||||
After you upgrade, decrypting affected values fails by default — add `ignore-cipher-failure=1` to read them:
|
||||
|
||||
```sql
|
||||
update <your_table>
|
||||
set <col> = pgp_sym_encrypt(
|
||||
pgp_sym_decrypt(<col>, '<your-key>', 'ignore-cipher-failure=1'),
|
||||
'<your-key>', 'cipher-algo=aes256')
|
||||
where <id_column> in (/* rows found by the scan above */);
|
||||
```
|
||||
|
||||
If the plaintext is binary (encrypted with `pgp_sym_encrypt_bytea`), use `pgp_sym_decrypt_bytea` and `pgp_sym_encrypt_bytea` in the same way — the text functions reject binary plaintext. Spot-check that a recovered value decrypts to the expected plaintext before running the update across all rows. Because affected values were not protected as intended, consider rotating any secrets stored this way.
|
||||
|
||||
### Btree_gist indexes on float columns require reindexing after upgrade
|
||||
|
||||
_Applies when upgrading to Postgres 15.19 or 17.11._
|
||||
|
||||
@@ -350,6 +350,8 @@ allow_list = [
|
||||
"PGroonga",
|
||||
"pg_basebackup",
|
||||
"PgBouncer",
|
||||
"pgcrypto",
|
||||
"Pgcrypto",
|
||||
"pgjwt",
|
||||
"PHI",
|
||||
"Pico",
|
||||
|
||||
Reference in new issue
Block a user