mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Merge pull request #1293 from HackTricks-wiki/update_Rare_Case_of_Privilege_Escalation_in_ASE_Plugin_Af_20250816_124250
Rare Case of Privilege Escalation in ASE Plugin Affecting 10...
This commit is contained in:
		
						commit
						8f05795af8
					
				@ -490,6 +490,76 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Many plugins implement a "view as role" or temporary role-switching feature by saving the original role(s) in user meta so they can be restored later. If the restoration path relies only on request parameters (e.g., `$_REQUEST['reset-for']`) and a plugin-maintained list without checking capabilities and a valid nonce, this becomes a vertical privilege escalation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A real-world example was found in the Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). The reset branch restored roles based on `reset-for=<username>` if the username appeared in an internal array `$options['viewing_admin_as_role_are']`, but performed neither a `current_user_can()` check nor a nonce verification before removing current roles and re-adding the saved roles from user meta `_asenha_view_admin_as_original_roles`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```php
 | 
				
			||||||
 | 
					// Simplified vulnerable pattern
 | 
				
			||||||
 | 
					if ( isset( $_REQUEST['reset-for'] ) ) {
 | 
				
			||||||
 | 
					    $reset_for_username = sanitize_text_field( $_REQUEST['reset-for'] );
 | 
				
			||||||
 | 
					    $usernames = get_option( ASENHA_SLUG_U, [] )['viewing_admin_as_role_are'] ?? [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( in_array( $reset_for_username, $usernames, true ) ) {
 | 
				
			||||||
 | 
					        $u = get_user_by( 'login', $reset_for_username );
 | 
				
			||||||
 | 
					        foreach ( $u->roles as $role ) { $u->remove_role( $role ); }
 | 
				
			||||||
 | 
					        $orig = (array) get_user_meta( $u->ID, '_asenha_view_admin_as_original_roles', true );
 | 
				
			||||||
 | 
					        foreach ( $orig as $r ) { $u->add_role( $r ); }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Why it’s exploitable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Trusts `$_REQUEST['reset-for']` and a plugin option without server-side authorization.
 | 
				
			||||||
 | 
					- If a user previously had higher privileges saved in `_asenha_view_admin_as_original_roles` and was downgraded, they can restore them by hitting the reset path.
 | 
				
			||||||
 | 
					- In some deployments, any authenticated user could trigger a reset for another username still present in `viewing_admin_as_role_are` (broken authorization).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Attack prerequisites
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Vulnerable plugin version with the feature enabled.
 | 
				
			||||||
 | 
					- Target account has a stale high-privilege role stored in user meta from earlier use.
 | 
				
			||||||
 | 
					- Any authenticated session; missing nonce/capability on the reset flow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exploitation (example)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# While logged in as the downgraded user (or any auth user able to trigger the code path),
 | 
				
			||||||
 | 
					# hit any route that executes the role-switcher logic and include the reset parameter.
 | 
				
			||||||
 | 
					# The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks.
 | 
				
			||||||
 | 
					curl -s -k -b 'wordpress_logged_in=...' \
 | 
				
			||||||
 | 
					  'https://victim.example/wp-admin/?reset-for=<your_username>'
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					On vulnerable builds this removes current roles and re-adds the saved original roles (e.g., `administrator`), effectively escalating privileges.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Detection checklist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Look for role-switching features that persist “original roles” in user meta (e.g., `_asenha_view_admin_as_original_roles`).
 | 
				
			||||||
 | 
					- Identify reset/restore paths that:
 | 
				
			||||||
 | 
					  - Read usernames from `$_REQUEST` / `$_GET` / `$_POST`.
 | 
				
			||||||
 | 
					  - Modify roles via `add_role()` / `remove_role()` without `current_user_can()` and `wp_verify_nonce()` / `check_admin_referer()`.
 | 
				
			||||||
 | 
					  - Authorize based on a plugin option array (e.g., `viewing_admin_as_role_are`) instead of the actor’s capabilities.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hardening
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Enforce capability checks on every state-changing branch (e.g., `current_user_can('manage_options')` or stricter).
 | 
				
			||||||
 | 
					- Require nonces for all role/permission mutations and verify them: `check_admin_referer()` / `wp_verify_nonce()`.
 | 
				
			||||||
 | 
					- Never trust request-supplied usernames; resolve the target user server-side based on the authenticated actor and explicit policy.
 | 
				
			||||||
 | 
					- Invalidate “original roles” state on profile/role updates to avoid stale high-privilege restoration:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```php
 | 
				
			||||||
 | 
					add_action( 'profile_update', function( $user_id ) {
 | 
				
			||||||
 | 
					    delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
 | 
				
			||||||
 | 
					}, 10, 1 );
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Consider storing minimal state and using time-limited, capability-guarded tokens for temporary role switches.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## WordPress Protection
 | 
					## WordPress Protection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Regular Updates
 | 
					### Regular Updates
 | 
				
			||||||
@ -584,5 +654,7 @@ The server responds with the contents of `wp-config.php`, leaking DB credentials
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
 | 
					- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
 | 
				
			||||||
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
 | 
					- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
 | 
				
			||||||
 | 
					- [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
 | 
				
			||||||
 | 
					- [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{#include ../../banners/hacktricks-training.md}}
 | 
					{{#include ../../banners/hacktricks-training.md}}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user