Skip to content

Commit 0964835

Browse files
committed
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. git-svn-id: https://develop.svn.wordpress.org/trunk@61687 602fd350-edb4-49c9-b593-d223f7449a82
1 parent ee7a6d8 commit 0964835

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

src/wp-admin/includes/class-wp-site-health.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,42 @@ public function get_test_available_updates_disk_space() {
18821882
return $result;
18831883
}
18841884

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+
);
1916+
}
1917+
1918+
return $result;
1919+
}
1920+
18851921
/**
18861922
* Tests if plugin and theme temporary backup directories are writable or can be created.
18871923
*
@@ -2889,6 +2925,10 @@ public static function get_tests() {
28892925
'label' => __( 'Autoloaded options' ),
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' ),
28942934
'test' => 'search_engine_visibility',

src/wp-admin/includes/template.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -967,13 +967,18 @@ function parent_dropdown( $default_page = 0, $parent_page = 0, $level = 0, $post
967967
* Prints out option HTML elements for role selectors.
968968
*
969969
* @since 2.1.0
970+
* @since 7.0.0 Added $editable_roles parameter.
970971
*
971-
* @param string $selected Slug for the role that should be already selected.
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.
972975
*/
973-
function wp_dropdown_roles( $selected = '' ) {
976+
function 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 ) {
979984
$name = translate_user_role( $details['name'] );

src/wp-admin/options-general.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,28 @@ class="<?php echo esc_attr( $classes_for_button ); ?>"
304304
<tr>
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>
310331

0 commit comments

Comments
 (0)