# Capability Audit for Risky Permissions

> Adds Users > Capability Audit, listing every role other than Administrator and every user outside the administrator role that holds powerful permissions such as unfiltered HTML, plugin installation or user management.

- Type: PHP
- Runs: Admin only
- Category: [Security](https://wpide.com/library/category/security/)
- Tags: capabilities, roles, audit
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/sec-capability-audit/

## Code

```php
// Capabilities considered risky outside the administrator role.
$wpide_risky_caps = array( 'unfiltered_html', 'unfiltered_upload', 'edit_plugins', 'edit_themes', 'edit_files', 'install_plugins', 'activate_plugins', 'delete_plugins', 'install_themes', 'switch_themes', 'update_core', 'manage_options', 'promote_users', 'create_users', 'edit_users', 'delete_users' );

add_action( 'admin_menu', function () use ( $wpide_risky_caps ) {
    add_users_page( 'Capability Audit', 'Capability Audit', 'promote_users', 'wpide-cap-audit', function () use ( $wpide_risky_caps ) {
        echo '<div class="wrap"><h1>Capability Audit</h1><h2>Roles</h2><table class="widefat striped" style="max-width:900px"><thead><tr><th>Role</th><th>Risky capabilities</th></tr></thead><tbody>';
        $flagged_roles = 0;
        foreach ( wp_roles()->roles as $slug => $role ) {
            if ( 'administrator' === $slug ) {
                continue;
            }
            $risky = array_keys( array_intersect_key( array_filter( (array) $role['capabilities'] ), array_flip( $wpide_risky_caps ) ) );
            if ( $risky ) {
                $flagged_roles++;
                printf( '<tr><td>%s <code>%s</code></td><td>%s</td></tr>', esc_html( translate_user_role( $role['name'] ) ), esc_html( $slug ), esc_html( implode( ', ', $risky ) ) );
            }
        }
        if ( ! $flagged_roles ) {
            echo '<tr><td colspan="2">No role besides Administrator has risky capabilities.</td></tr>';
        }
        echo '</tbody></table><h2>Users with extra capabilities</h2><table class="widefat striped" style="max-width:900px"><thead><tr><th>User</th><th>Roles</th><th>Risky capabilities</th></tr></thead><tbody>';
        $flagged_users = 0;
        foreach ( get_users( array( 'role__not_in' => array( 'administrator' ), 'number' => 500, 'fields' => 'all' ) ) as $user ) {
            $risky = array();
            foreach ( $wpide_risky_caps as $cap ) {
                if ( ! empty( $user->allcaps[ $cap ] ) ) {
                    $risky[] = $cap;
                }
            }
            if ( $risky ) {
                $flagged_users++;
                printf( '<tr><td><a href="%s">%s</a></td><td>%s</td><td>%s</td></tr>', esc_url( get_edit_user_link( $user->ID ) ), esc_html( $user->user_login ), esc_html( implode( ', ', $user->roles ) ), esc_html( implode( ', ', $risky ) ) );
            }
        }
        if ( ! $flagged_users ) {
            echo '<tr><td colspan="3">No non-administrator has risky capabilities.</td></tr>';
        }
        echo '</tbody></table></div>';
    } );
} );
```

## Notes

Plugins sometimes grant extra capabilities to editors or shop managers; review anything you did not set up yourself.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Capability Audit for Risky Permissions" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
