Make WordPress Core


Ignore:
Timestamp:
10/27/2020 06:30:03 PM (4 years ago)
Author:
TimothyBlynJacobs
Message:

Site Health, App Passwords: Test if the Authorization header is populated correctly.

App Passwords rely on the Authorization header to transport the Basic Auth credentials. For Apache web servers, WordPress automatically includes a RewriteRule to populate the value for servers running in CGI or FastCGI that wouldn't ordinarily populate the value.

This tests if the header is being filled with the expected values. For Apache users, we direct the user to visit the Permalinks settings to flush their permalinks. For all other users, we direct them to a help document on developer.wordpress.org.

Props Clorith, marybaum, TimothyBlynJacobs.
Fixes #51638.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-site-health.php

    r49266 r49334  
    136136                        'has_rest'  => ( isset( $test['has_rest'] ) ? $test['has_rest'] : false ),
    137137                        'completed' => false,
     138                        'headers'   => isset( $test['headers'] ) ? $test['headers'] : array(),
    138139                    );
    139140                }
     
    20742075            );
    20752076            return $result;
     2077        }
     2078
     2079        return $result;
     2080    }
     2081
     2082    /**
     2083     * Tests if the Authorization header has the expected values.
     2084     *
     2085     * @since 5.6.0
     2086     *
     2087     * @return array
     2088     */
     2089    public function get_test_authorization_header() {
     2090        $result = array(
     2091            'label'       => __( 'The Authorization header is working as expected.' ),
     2092            'status'      => 'good',
     2093            'badge'       => array(
     2094                'label' => __( 'Security' ),
     2095                'color' => 'blue',
     2096            ),
     2097            'description' => sprintf(
     2098                '<p>%s</p>',
     2099                __( 'The Authorization header comes from the third-party applications you approve. Without it, those apps cannot connect to your site.' )
     2100            ),
     2101            'actions'     => '',
     2102            'test'        => 'authorization_header',
     2103        );
     2104
     2105        if ( ! isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) {
     2106            $result['label'] = __( 'The authorization header is missing.' );
     2107        } elseif ( 'user' !== $_SERVER['PHP_AUTH_USER'] || 'pwd' !== $_SERVER['PHP_AUTH_PW'] ) {
     2108            $result['label'] = __( 'The authorization header is invalid.' );
     2109        } else {
     2110            return $result;
     2111        }
     2112
     2113        $result['status'] = 'recommended';
     2114
     2115        if ( ! function_exists( 'got_mod_rewrite' ) ) {
     2116            require_once ABSPATH . 'wp-admin/includes/misc.php';
     2117        }
     2118
     2119        if ( got_mod_rewrite() ) {
     2120            $result['actions'] .= sprintf(
     2121                '<p><a href="%s">%s</a></p>',
     2122                esc_url( admin_url( 'options-permalink.php' ) ),
     2123                __( 'Flush permalinks' )
     2124            );
     2125        } else {
     2126            $result['actions'] .= sprintf(
     2127                '<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
     2128                'https://developer.wordpress.org/rest-api/frequently-asked-questions/#why-is-authentication-not-working',
     2129                __( 'Learn how to configure the Authorization header.' ),
     2130                /* translators: Accessibility text. */
     2131                __( '(opens in a new tab)' )
     2132            );
    20762133        }
    20772134
     
    21782235                    'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_loopback_requests' ),
    21792236                ),
     2237                'authorization_header' => array(
     2238                    'label'     => __( 'Authorization header' ),
     2239                    'test'      => rest_url( 'wp-site-health/v1/tests/authorization-header' ),
     2240                    'has_rest'  => true,
     2241                    'headers'   => array( 'Authorization' => 'Basic ' . base64_encode( 'user:pwd' ) ),
     2242                    'skip_cron' => true,
     2243                ),
    21802244            ),
    21812245        );
     
    22042268         * @since 5.2.0
    22052269         * @since 5.6.0 Added the `async_direct_test` array key.
     2270         *              Added the `skip_cron` array key.
    22062271         *
    22072272         * @param array $test_type {
     
    22182283         *                                           to be called to perform an async test.
    22192284         *         @type boolean  $has_rest          Optional. Denote if `$test` has a REST API endpoint.
     2285         *         @type boolean  $skip_cron         Whether to skip this test when running as cron.
    22202286         *         @type callable $async_direct_test A manner of directly calling the test marked as asynchronous,
    22212287         *                                           as the scheduled event can not authenticate, and endpoints
     
    25582624
    25592625        foreach ( $tests['async'] as $test ) {
     2626            if ( ! empty( $test['skip_cron'] ) ) {
     2627                continue;
     2628            }
     2629
    25602630            // Local endpoints may require authentication, so asynchronous tests can pass a direct test runner as well.
    25612631            if ( ! empty( $test['async_direct_test'] ) && is_callable( $test['async_direct_test'] ) ) {
Note: See TracChangeset for help on using the changeset viewer.