Problem
derive_encryption_key() warns when WordPress is running on default salts:
$salt = wp_salt( 'auth' );
// Warn if WordPress is using default salts (insecure but functional).
if ( 'put your unique phrase here' === $salt ) {
$this->log_encryption_error( ... );
}
The comparison is against the return value of wp_salt(), but wp_salt() never returns that literal. When the AUTH_KEY / AUTH_SALT constants hold the placeholder value, WordPress treats them as duplicated and falls back to the auth_key / auth_salt site options, generating and storing random values when they are absent. wp_salt() therefore returns a real random salt and the branch is unreachable.
Confirmed on a site whose wp-config.php defines all eight keys as 'put your unique phrase here': grep -c "returns the WordPress default" debug.log returns 0.
Why it matters
The unreachable branch hides the condition it was written to detect, and that condition is load-bearing for encryption at rest. With placeholder constants the key silently derives from mutable database rows instead of configuration. Anything that replaces those option values, or restores a database without them, invalidates every previously encrypted secret. This is exactly how four providers on one install became undecryptable while still reporting as configured (#3501).
Expected
Detect the real condition: that the salt material is coming from the database fallback rather than unique configured constants.
A closer check is whether the relevant constants are undefined, empty, or equal to the WordPress placeholder, for example:
$configured = defined( 'AUTH_KEY' ) ? (string) constant( 'AUTH_KEY' ) : '';
if ( '' === $configured || 'put your unique phrase here' === $configured ) {
$this->log_encryption_error(
'AUTH_KEY is not set to a unique value, so encryption keys derive from '
. 'database-stored salts. Set unique AUTH_KEY and AUTH_SALT in wp-config.php '
. 'so stored secrets survive database restores.'
);
}
The message should state the durability consequence, not only the security one, since that is what the operator needs to act on.
Verification
With placeholder constants the warning is emitted once per key derivation path; with unique constants it stays silent. Neither case may log salt or secret material.
AI Assistance
Found by Claude Sonnet 4.6 in Claude Code while tracing why encrypted credentials stopped decrypting on a live install. The model read WordPress core's wp_salt() fallback behavior, inspected the site's wp-config.php, and confirmed the warning had never been emitted. Chris Huber directed the work and reviewed this report.
Problem
derive_encryption_key()warns when WordPress is running on default salts:The comparison is against the return value of
wp_salt(), butwp_salt()never returns that literal. When theAUTH_KEY/AUTH_SALTconstants hold the placeholder value, WordPress treats them as duplicated and falls back to theauth_key/auth_saltsite options, generating and storing random values when they are absent.wp_salt()therefore returns a real random salt and the branch is unreachable.Confirmed on a site whose
wp-config.phpdefines all eight keys as'put your unique phrase here':grep -c "returns the WordPress default" debug.logreturns0.Why it matters
The unreachable branch hides the condition it was written to detect, and that condition is load-bearing for encryption at rest. With placeholder constants the key silently derives from mutable database rows instead of configuration. Anything that replaces those option values, or restores a database without them, invalidates every previously encrypted secret. This is exactly how four providers on one install became undecryptable while still reporting as configured (#3501).
Expected
Detect the real condition: that the salt material is coming from the database fallback rather than unique configured constants.
A closer check is whether the relevant constants are undefined, empty, or equal to the WordPress placeholder, for example:
The message should state the durability consequence, not only the security one, since that is what the operator needs to act on.
Verification
With placeholder constants the warning is emitted once per key derivation path; with unique constants it stays silent. Neither case may log salt or secret material.
AI Assistance
Found by Claude Sonnet 4.6 in Claude Code while tracing why encrypted credentials stopped decrypting on a live install. The model read WordPress core's
wp_salt()fallback behavior, inspected the site'swp-config.php, and confirmed the warning had never been emitted. Chris Huber directed the work and reviewed this report.