Skip to content

Default-salt warning cannot fire when wp-config uses placeholder salts #3502

Description

@chubes4

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions