close

Make WordPress Core

Changeset 61687


Ignore:
Timestamp:
02/19/2026 09:42:59 AM (3 weeks ago)
Author:
audrasjb
Message:

Administration: Warn when open registration and new user default is privileged.

Previously, WordPress allowed site owners to open registration AND to set the default new user level to "Administrator" or "Editor". While this combination may make sense for some sites, this is genrally a really really bad idea.

With this changeset:

  • Administrator and Editor roles are now removed from the new user default role selector in the General Options admin screen.
  • If such a role was selected before, an alert is shown in Site Health.
  • A new filter is introduced: default_role_dropdown_excluded_roles allows developers to change the default excluded roles in the dropdown.

Props kraftbj, subrataemfluence, roytanck, dd32, ottok, jrf, eatingrules, verygoode, generosus, stevejburge, arunu1996, benniledl, audrasjb, mukesh27, swissspidy, Mte90, zodiac1978, pooja1210, davidbaumwald, johnbillion, jorbin, SirLouen, oglekler, kirasong, shailu25, huzaifaalmesbah, jsmansart.
Fixes #43936.

Location:
trunk/src/wp-admin
Files:
3 edited

Legend:

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

    r61612 r61687  
    18781878            );
    18791879            $result['status'] = 'recommended';
     1880        }
     1881
     1882        return $result;
     1883    }
     1884
     1885    /**
     1886     * Tests if registration is open to everyone and the default role is privileged.
     1887     *
     1888     * @since 7.0.0
     1889     *
     1890     * @return array The test results.
     1891     */
     1892    public function get_test_insecure_registration() {
     1893        $users_can_register = get_option( 'users_can_register' );
     1894        $default_role       = get_option( 'default_role' );
     1895
     1896        $result = array(
     1897            'label'       => __( 'Open Registration with privileged default role' ),
     1898            'status'      => 'good',
     1899            'badge'       => array(
     1900                'label' => __( 'Security' ),
     1901                'color' => 'blue',
     1902            ),
     1903            'description' => '<p>' . __( 'The combination of open registration setting and the default user role may lead to security issues.' ) . '</p>',
     1904            'actions'     => '',
     1905            'test'        => 'insecure_registration',
     1906        );
     1907
     1908        if ( $users_can_register && in_array( $default_role, array( 'editor', 'administrator' ), true ) ) {
     1909            $result['description'] = __( 'Registration is open to anyone, and the default role is set to a privileged role.' );
     1910            $result['status']      = 'critical';
     1911            $result['actions']     = sprintf(
     1912                '<p><a href="%s">%s</a></p>',
     1913                esc_url( admin_url( 'options-general.php' ) ),
     1914                __( 'Change these settings' )
     1915            );
    18801916        }
    18811917
     
    28902926                    'test'  => 'autoloaded_options',
    28912927                ),
     2928                'insecure_registration'        => array(
     2929                    'label' => __( 'Open Registration with privileged default role' ),
     2930                    'test'  => 'insecure_registration',
     2931                ),
    28922932                'search_engine_visibility'     => array(
    28932933                    'label' => __( 'Search Engine Visibility' ),
  • trunk/src/wp-admin/includes/template.php

    r61681 r61687  
    968968 *
    969969 * @since 2.1.0
    970  *
    971  * @param string $selected Slug for the role that should be already selected.
    972  */
    973 function wp_dropdown_roles( $selected = '' ) {
     970 * @since 7.0.0 Added $editable_roles parameter.
     971 *
     972 * @param string $selected       Slug for the role that should be already selected.
     973 * @param array  $editable_roles Array of roles to include in the dropdown. Defaults to all
     974 *                               roles the current user is allowed to edit.
     975 */
     976function wp_dropdown_roles( $selected = '', $editable_roles = null ) {
    974977    $r = '';
    975978
    976     $editable_roles = array_reverse( get_editable_roles() );
     979    if ( null === $editable_roles ) {
     980        $editable_roles = array_reverse( get_editable_roles() );
     981    }
    977982
    978983    foreach ( $editable_roles as $role => $details ) {
  • trunk/src/wp-admin/options-general.php

    r61193 r61687  
    305305<th scope="row"><label for="default_role"><?php _e( 'New User Default Role' ); ?></label></th>
    306306<td>
    307 <select name="default_role" id="default_role"><?php wp_dropdown_roles( get_option( 'default_role' ) ); ?></select>
     307    <?php
     308    /**
     309     * Filters the roles to be excluded from the default_role option.
     310     *
     311     * @since 7.0.0
     312     *
     313     * @param string[] $roles_to_exclude Array of roles to exclude from the dropdown.
     314     *                                   Defaults to administrator and editor.
     315     */
     316    $excluded_roles = (array) apply_filters( 'default_role_dropdown_excluded_roles', array( 'administrator', 'editor' ) );
     317
     318    $editable_roles = array_reverse( get_editable_roles() );
     319
     320    $selected = get_option( 'default_role' );
     321
     322    foreach ( $editable_roles as $role => $details ) {
     323        if ( in_array( $role, $excluded_roles, true ) && $role !== $selected ) {
     324            unset( $editable_roles[ $role ] );
     325        }
     326    }
     327    ?>
     328    <select name="default_role" id="default_role"><?php wp_dropdown_roles( $selected, $editable_roles ); ?></select>
    308329</td>
    309330</tr>
Note: See TracChangeset for help on using the changeset viewer.