Repository navigation
Secrets API: Generate WP_SECRETS_KEY during installation
#15124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -390,13 +390,29 @@ function setup_config_display_header( $body_classes = array() ) { | |
| } | ||
| } | ||
|
|
||
| $key = 0; | ||
| /* | ||
| * The Secrets API key is generated like the salts above, but written as base64-encoded | ||
| * random bytes, the form the Secrets API uses as raw key material. | ||
| */ | ||
| try { | ||
| $secrets_key = base64_encode( random_bytes( 32 ) ); | ||
| } catch ( Exception $ex ) { | ||
| $secrets_key = wp_generate_password( 64, true, true ); | ||
| } | ||
|
|
||
| $key = 0; | ||
| $has_secrets_key = false; | ||
| foreach ( $config_file as $line_num => $line ) { | ||
| if ( str_starts_with( $line, '$table_prefix =' ) ) { | ||
| $config_file[ $line_num ] = '$table_prefix = \'' . addcslashes( $prefix, "\\'" ) . "';\r\n"; | ||
| continue; | ||
| } | ||
|
|
||
| if ( isset( $nonce_salt_line ) && ! isset( $salts_end_line ) && '/**#@-*/' === trim( $line ) ) { | ||
| $salts_end_line = $line_num; | ||
| continue; | ||
| } | ||
|
|
||
| if ( ! preg_match( '/^define\(\s*\'([A-Z_]+)\',([ ]+)/', $line, $match ) ) { | ||
| continue; | ||
| } | ||
|
|
@@ -426,10 +442,36 @@ function setup_config_display_header( $body_classes = array() ) { | |
| case 'NONCE_SALT': | ||
| $config_file[ $line_num ] = "define( '" . $constant . "'," . $padding . "'" . $secret_keys[ $key++ ] . "' );\r\n"; | ||
| break; | ||
| case 'WP_SECRETS_KEY': | ||
| $config_file[ $line_num ] = "define( '" . $constant . "'," . $padding . "'" . $secrets_key . "' );\r\n"; | ||
| $has_secrets_key = true; | ||
| break; | ||
| } | ||
|
|
||
| if ( 'NONCE_SALT' === $constant ) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a little flakey if additional secrets are added to the sample config file. I also think it a good idea to add this to the sample config file but let me know if there are reasons you don't wish to do this. I suggest adding this above the /**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', '...' );
define( 'SECURE_AUTH_KEY', '...' );
define( 'LOGGED_IN_KEY', '...' );
define( 'NONCE_KEY', '...' );
define( 'AUTH_SALT', '...' );
define( 'SECURE_AUTH_SALT', '...' );
define( 'LOGGED_IN_SALT', '...' );
define( 'NONCE_SALT', '...' );
/**
* Encryption key for the Secrets API.
*
* Secrets stored by WordPress and plugins are encrypted with this key.
* Unlike the keys and salts above, changing it makes every stored secret unreadable.
*
* @since 7.2.0
*/
define( 'WP_SECRETS_KEY', '...' );
/**#@-*/
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. The sample now defines I put it after |
||
| $nonce_salt_line = $line_num; | ||
| } | ||
| } | ||
| unset( $line ); | ||
|
|
||
| // A custom or older localized wp-config-sample.php may not define the key: add it after the salts. | ||
| if ( ! $has_secrets_key && isset( $nonce_salt_line ) ) { | ||
| $secrets_key_lines = array( | ||
| "\r\n", | ||
| "/**\r\n", | ||
| " * Encryption key for the Secrets API.\r\n", | ||
| " *\r\n", | ||
| " * Secrets stored by WordPress and plugins are encrypted with this key.\r\n", | ||
| " * Unlike the keys and salts above, changing it makes every stored secret unreadable.\r\n", | ||
| " *\r\n", | ||
| " * @since 7.2.0\r\n", | ||
| " */\r\n", | ||
| "define( 'WP_SECRETS_KEY', '" . $secrets_key . "' );\r\n", | ||
| ); | ||
|
|
||
| array_splice( $config_file, ( $salts_end_line ?? $nonce_salt_line ) + 1, 0, $secrets_key_lines ); | ||
| } | ||
|
|
||
| if ( ! is_writable( ABSPATH ) ) : | ||
| setup_config_display_header(); | ||
| ?> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -59,6 +59,17 @@ | |||||
|
|
||||||
| /**#@-*/ | ||||||
|
|
||||||
| /** | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does phpDocumentor allow for multiple placeholders? If so, it might be useful but it's not a big problem if it doesn't.
Suggested change
|
||||||
| * Encryption key for the Secrets API. | ||||||
| * | ||||||
| * Secrets stored by WordPress and plugins are encrypted with this key. Change it to | ||||||
| * a unique phrase, different from the keys and salts above. Unlike them, it must not | ||||||
| * be changed once secrets are stored: that makes every stored secret unreadable. | ||||||
| * | ||||||
| * @since 7.2.0 | ||||||
| */ | ||||||
| define( 'WP_SECRETS_KEY', 'put your unique phrase here' ); | ||||||
|
|
||||||
| /** | ||||||
| * WordPress database table prefix. | ||||||
| * | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other values fall back to
wp_generate_password()if CSPRING isn't available. It might be worth doing so here too.On the ticket I've suggested coordinating with meta to have
WP_SECRETS_KEYadded to the secrets API to allow this to fall back to the API if needs be.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 6c93419. Without a CSPRNG it now uses
wp_generate_password( 64, true, true ), like the salts. With the fallback removed in #15258, a weaker key is better than none. I've replied on Trac about the API: it should be a separate endpoint, because people paste the/1.1/salt/output to rotate their salts.