WordPress build repository browser

Changeset 64529


Ignore:
Timestamp:
11/10/2026 04:00:02 PM (7 hours ago)
Author:
whyisjake
Message:

Security: Make the Secrets API extension points abstract classes.

WP_Secrets_Provider, WP_Secrets_Store and WP_Secrets_Keyring were interfaces. Once they ship, adding a method to one would be a fatal error in every secrets.php drop-in that implements it, so they could never change. As abstract classes, a later release can add a method with a default implementation and existing drop-ins keep working.

The method signatures are unchanged. The three files are renamed from interface-wp-secrets-*.php to class-wp-secrets-*.php, and the default and fail-closed implementations now extend the classes.

A drop-in written against the interfaces must change implements to extends. Until it does, loading it is a fatal error.

Follow-up to r64337, r65375.

Props ericmann, jorbin.
See #66187.

Built from ​https://develop.svn.wordpress.org/trunk@65390

Location:
trunk
Files:
3 added
3 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/load.php

    r64517 r64529  
    829829 * Secrets API's provider, store, and keyring overrides in a usable state.
    830830 *
    831  * Runs once, before must-use plugins load, so that every interface a drop-in's
    832  * classes implement already exists and every plugin sees the drop-in's provider.
     831 * Runs once, before must-use plugins load, so that every class a drop-in's classes
     832 * extend already exists and every plugin sees the drop-in's provider.
    833833 *
    834834 * The drop-in sets its overrides in the `$wp_secrets_provider`, `$wp_secrets_store`
    … …  
    842842 * Sets `$GLOBALS['wp_secrets_dropin_broken']` when the require throws, or when any of
    843843 * `$GLOBALS['wp_secrets_provider']`, `$GLOBALS['wp_secrets_store']`, or
    844  * `$GLOBALS['wp_secrets_keyring']` is set to something that does not implement its
    845  * interface. A global left unset is fine: a drop-in that overrides only the keyring
     844 * `$GLOBALS['wp_secrets_keyring']` is set to something that does not extend its
     845 * class. A global left unset is fine: a drop-in that overrides only the keyring
    846846 * leaves the other two alone. Once the flag is set, every Secrets API operation
    847847 * returns WP_Error for the rest of the request rather than falling back to the
    848848 * default provider, so a broken drop-in reads as unreachable, never as absent.
    849849 *
    850  * PHP treats a class that implements an interface but omits a required method as an
    851  * uncatchable fatal error, even inside the try/catch around the require. That case
     850 * PHP treats a class that extends an abstract class but omits one of its abstract
     851 * methods as an uncatchable fatal error, even inside the try/catch around the require. That case
    852852 * cannot be intercepted from PHP code.
    853853 *
  • trunk/wp-includes/secrets/class-wp-secrets-broken-keyring.php

    r64514 r64529  
    2121 * @since 7.2.0
    2222 */
    23 final class WP_Secrets_Broken_Keyring implements WP_Secrets_Keyring {
     23final class WP_Secrets_Broken_Keyring extends WP_Secrets_Keyring {
    2424
    2525        /**
  • trunk/wp-includes/secrets/class-wp-secrets-broken-provider.php

    r64514 r64529  
    2323 * @since 7.2.0
    2424 */
    25 final class WP_Secrets_Broken_Provider implements WP_Secrets_Provider {
     25final class WP_Secrets_Broken_Provider extends WP_Secrets_Provider {
    2626
    2727        /**
  • trunk/wp-includes/secrets/class-wp-secrets-broken-store.php

    r64421 r64529  
    2222 * @since 7.2.0
    2323 */
    24 final class WP_Secrets_Broken_Store implements WP_Secrets_Store {
     24final class WP_Secrets_Broken_Store extends WP_Secrets_Store {
    2525
    2626        /**
  • trunk/wp-includes/secrets/class-wp-secrets-config-key-provider.php

    r64524 r64529  
    3939 * @since 7.2.0
    4040 */
    41 final class WP_Secrets_Config_Key_Provider implements WP_Secrets_Keyring {
     41final class WP_Secrets_Config_Key_Provider extends WP_Secrets_Keyring {
    4242
    4343        /**
  • trunk/wp-includes/secrets/class-wp-secrets-libsodium-provider.php

    r64514 r64529  
    1414 *
    1515 * This is the default rather than a privileged case. Everything it does is expressed
    16  * through WP_Secrets_Provider, the same interface a platform implements, so a KMS-
     16 * through WP_Secrets_Provider, the same class a platform extends, so a KMS-
    1717 * or HSM-backed provider is a peer rather than an exception carved into the side of
    1818 * this one.
    … …  
    3333 * @since 7.2.0
    3434 */
    35 final class WP_Secrets_Libsodium_Provider implements WP_Secrets_Provider {
     35final class WP_Secrets_Libsodium_Provider extends WP_Secrets_Provider {
    3636
    3737        /**
  • trunk/wp-includes/secrets/class-wp-secrets-option-store.php

    r64421 r64529  
    2222 * @since 7.2.0
    2323 */
    24 final class WP_Secrets_Option_Store implements WP_Secrets_Store {
     24final class WP_Secrets_Option_Store extends WP_Secrets_Store {
    2525
    2626        /**
  • trunk/wp-includes/version.php

    r64528 r64529  
    1717 * @global string $wp_version
    1818 */
    19 $wp_version = '7.2-beta4-65389';
     19$wp_version = '7.2-beta4-65390';
    2020
    2121/**
  • trunk/wp-settings.php

    r63881 r64529  
    325325require ABSPATH . WPINC . '/secrets/class-wp-secret-version.php';
    326326require ABSPATH . WPINC . '/secrets/class-wp-secret.php';
    327 require ABSPATH . WPINC . '/secrets/interface-wp-secrets-provider.php';
    328 require ABSPATH . WPINC . '/secrets/interface-wp-secrets-keyring.php';
    329 require ABSPATH . WPINC . '/secrets/interface-wp-secrets-store.php';
     327require ABSPATH . WPINC . '/secrets/class-wp-secrets-provider.php';
     328require ABSPATH . WPINC . '/secrets/class-wp-secrets-keyring.php';
     329require ABSPATH . WPINC . '/secrets/class-wp-secrets-store.php';
    330330require ABSPATH . WPINC . '/secrets/class-wp-secrets-config-key-provider.php';
    331331require ABSPATH . WPINC . '/secrets/class-wp-secrets-broken-keyring.php';
Note: See TracChangeset for help on using the changeset viewer.