diff options
author | Nathan Bossart <nathan@postgresql.org> | 2024-12-02 13:30:07 -0600 |
---|---|---|
committer | Nathan Bossart <nathan@postgresql.org> | 2024-12-02 13:30:07 -0600 |
commit | db6a4a985bc09d260d5c29848e3c97f080646a53 (patch) | |
tree | 5d57a50559a2a1ae40896a2007a9025a12339f22 /src | |
parent | 97173536ed4b1c29dce0dc4119db136e142f60a2 (diff) | |
download | postgresql-db6a4a985bc09d260d5c29848e3c97f080646a53.tar.gz postgresql-db6a4a985bc09d260d5c29848e3c97f080646a53.zip |
Deprecate MD5 passwords.
MD5 has been considered to be unsuitable for use as a cryptographic
hash algorithm for some time. Furthermore, MD5 password hashes in
PostgreSQL are vulnerable to pass-the-hash attacks, i.e., knowing
the username and hashed password is sufficient to authenticate.
The SCRAM-SHA-256 method added in v10 is not subject to these
problems and is considered to be superior to MD5.
This commit marks MD5 password support in PostgreSQL as deprecated
and to be removed in a future release. The documentation now
contains several deprecation notices, and CREATE ROLE and ALTER
ROLE now emit deprecation warnings when setting MD5 passwords. The
warnings can be disabled by setting the md5_password_warnings
parameter to "off".
Reviewed-by: Greg Sabino Mullane, Jim Nasby
Discussion: https://postgr.es/m/ZwbfpJJol7lDWajL%40nathan
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/libpq/crypt.c | 10 | ||||
-rw-r--r-- | src/backend/utils/misc/guc_tables.c | 9 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 1 | ||||
-rw-r--r-- | src/include/libpq/crypt.h | 3 | ||||
-rw-r--r-- | src/test/regress/expected/password.out | 15 | ||||
-rw-r--r-- | src/test/regress/expected/password_1.out | 9 |
6 files changed, 47 insertions, 0 deletions
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index b01525dc28a..d37c70901b8 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -24,6 +24,8 @@ #include "utils/syscache.h" #include "utils/timestamp.h" +/* Enables deprecation warnings for MD5 passwords. */ +bool md5_password_warnings = true; /* * Fetch stored password for a user, for authentication. @@ -174,6 +176,14 @@ encrypt_password(PasswordType target_type, const char *role, MAX_ENCRYPTED_PASSWORD_LEN))); } + if (md5_password_warnings && + get_password_type(encrypted_password) == PASSWORD_TYPE_MD5) + ereport(WARNING, + (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE), + errmsg("setting an MD5-encrypted password"), + errdetail("MD5 password support is deprecated and will be removed in a future release of PostgreSQL."), + errhint("Refer to the PostgreSQL documentation for details about migrating to another password type."))); + return encrypted_password; } diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 9845abd6932..8cf1afbad20 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -2086,6 +2086,15 @@ struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"md5_password_warnings", PGC_USERSET, CONN_AUTH_AUTH, + gettext_noop("Enables deprecation warnings for MD5 passwords."), + }, + &md5_password_warnings, + true, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 407cd1e08ca..a2ac7575ca7 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -96,6 +96,7 @@ #authentication_timeout = 1min # 1s-600s #password_encryption = scram-sha-256 # scram-sha-256 or md5 #scram_iterations = 4096 +#md5_password_warnings = on # GSSAPI using Kerberos #krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h index 0bb44004353..db7ea7bd1f5 100644 --- a/src/include/libpq/crypt.h +++ b/src/include/libpq/crypt.h @@ -25,6 +25,9 @@ */ #define MAX_ENCRYPTED_PASSWORD_LEN (512) +/* Enables deprecation warnings for MD5 passwords. */ +extern PGDLLIMPORT bool md5_password_warnings; + /* * Types of password hashes or secrets. * diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.out index df3857460c2..9bb3ab2818b 100644 --- a/src/test/regress/expected/password.out +++ b/src/test/regress/expected/password.out @@ -14,8 +14,14 @@ SET password_encryption = 'scram-sha-256'; -- ok SET password_encryption = 'md5'; CREATE ROLE regress_passwd1; ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. CREATE ROLE regress_passwd2; ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. SET password_encryption = 'scram-sha-256'; CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3'; CREATE ROLE regress_passwd4 PASSWORD NULL; @@ -57,14 +63,23 @@ ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2; SET password_encryption = 'md5'; -- encrypt with MD5 ALTER ROLE regress_passwd2 PASSWORD 'foo'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. -- already encrypted, use as they are ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo='; SET password_encryption = 'scram-sha-256'; -- create SCRAM secret ALTER ROLE regress_passwd4 PASSWORD 'foo'; -- already encrypted with MD5, use as it is CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. -- This looks like a valid SCRAM-SHA-256 secret, but it is not -- so it should be hashed with SCRAM-SHA-256. CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234'; diff --git a/src/test/regress/expected/password_1.out b/src/test/regress/expected/password_1.out index bd0c2e48de0..8f613e976a6 100644 --- a/src/test/regress/expected/password_1.out +++ b/src/test/regress/expected/password_1.out @@ -61,12 +61,18 @@ ALTER ROLE regress_passwd2 PASSWORD 'foo'; ERROR: password encryption failed: unsupported -- already encrypted, use as they are ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo='; SET password_encryption = 'scram-sha-256'; -- create SCRAM secret ALTER ROLE regress_passwd4 PASSWORD 'foo'; -- already encrypted with MD5, use as it is CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. -- This looks like a valid SCRAM-SHA-256 secret, but it is not -- so it should be hashed with SCRAM-SHA-256. CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234'; @@ -100,6 +106,9 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+ CREATE ROLE regress_passwd_empty PASSWORD ''; NOTICE: empty string is not a valid password, clearing password ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a'; +WARNING: setting an MD5-encrypted password +DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL. +HINT: Refer to the PostgreSQL documentation for details about migrating to another password type. ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4='; NOTICE: empty string is not a valid password, clearing password SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty'; |