Headline
CVE-2023-1874: WPDA_Roles.php in wp-data-access/tags/5.3.8/WPDataRoles – WordPress Plugin Repository
The WP Data Access plugin for WordPress is vulnerable to privilege escalation in versions up to, and including, 5.3.7. This is due to a lack of authorization checks on the multiple_roles_update function. This makes it possible for authenticated attackers, with minimal permissions such as a subscriber, to modify their user role by supplying the 'wpda_role[]' parameter during a profile update. This requires the ‘Enable role management’ setting to be enabled for the site.
Line
1
<?php
2
3
/**
4
* Suppress “error - 0 - No summary was found for this file” on phpdoc generation
5
*
6
* @package WPDataRoles
7
*/
8
9
namespace WPDataRoles {
10
11
use WPDataAccess\\WPDA;
12
13
/\*\*
14
\* Class WPDA\_Roles
15
\*
16
\* Allow users to have multiple roles
17
\*
18
\* @author Peter Schulz
19
\* @since 2.7.0
20
\*/
21
class WPDA\_Roles {
22
23
private function can\_management\_roles() {
24
return
25
is\_admin() &&
26
current\_user\_can( 'promote\_users' ) &&
27
( 'off' !== WPDA::get\_option( WPDA::OPTION\_WPDA\_ENABLE\_ROLE\_MANAGEMENT ) );
28
}
29
30
/\*\*
31
\* @param $user
32
\*/
33
public function multiple\_roles\_selection( $user ) {
34
if ( ! $this\->can\_management\_roles() ) {
35
return;
36
}
37
38
$user\_roles \= isset( $user\->roles ) ? implode( "','", $user\->roles ) : '';
39
?>
40
<script type='text/javascript'>
41
jQuery('select\[name="role"\]').attr('multiple', 'yes').attr('size', '6').prop('name', 'wpda\_role\[\]');
42
jQuery('#role').val(\['<?php echo $user\_roles; // phpcs:ignore WordPress.Security.EscapeOutput ?>'\]);
43
</script\>
44
<?php
45
}
46
47
/\*\*
48
\* @param $user\_id
49
\*/
50
public function multiple\_roles\_update( $user\_id ) {
51
if ( ! $this\->can\_management\_roles() ) {
52
return;
53
}
54
55
$wp\_user \= new \\WP\_User( $user\_id );
56
if ( isset( $wp\_user\->data\->user\_login ) ) {
57
$user\_login \= $wp\_user\->data\->user\_login;
58
// Get access to editable roles
59
global $wp\_roles;
60
if ( isset( $\_REQUEST\['wpda\_role'\] ) && is\_array( $\_REQUEST\['wpda\_role'\] ) ) {
61
// Process roles
62
$sanitized\_roles \= array();
63
foreach ( $\_REQUEST\['wpda\_role'\] as $new\_user\_role ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
64
$sanitized\_new\_user\_role \= sanitize\_text\_field( wp\_unslash( $new\_user\_role ) ); // input var okay.
65
$wp\_user\->add\_role( $sanitized\_new\_user\_role );
66
$sanitized\_roles\[ $sanitized\_new\_user\_role \] \= true;
67
}
68
69
// Remove unselected roles
70
foreach ( $wp\_roles\->roles as $role \=> $val ) {
71
if ( ! isset( $sanitized\_roles\[ $role \] ) ) {
72
$wp\_user\->remove\_role( $role );
73
}
74
}
75
} else {
76
// REMOVED!!!
77
// When plugin role management is enabled, this removes all user roles when a user updates his profile.
78
// foreach ( $wp\_roles->roles as $role => $val ) {
79
// $wp\_user->remove\_role( $role );
80
// }
81
}
82
}
83
}
84
85
/\*\*
86
\* Change role label in user list table
87
\*
88
\* @param $columns
89
\*
90
\* @return mixed
91
\*/
92
public function multiple\_roles\_label( $columns ) {
93
if ( ! $this\->can\_management\_roles() ) {
94
return $columns;
95
}
96
97
$columns\['role'\] \= \_\_( 'Role(s)', 'wp-data-access' );
98
99
return $columns;
100
}
101
102
}
103
104
}