## https://sploitus.com/exploit?id=C74FAF75-8D62-595E-AB48-79B389DE5D29
# Admin Menu Groups
Create collapsible groups in the WordPress admin sidebar menu, reorder items, and hide the ones you don't use.
This is a **security-maintained fork** of [Admin Menu Groups](https://wordpress.org/plugins/admin-menu-groups/)
by Chaim Chaikin, which has been unmaintained since 2021.
## Why this fork exists
The upstream plugin carries an unpatched vulnerability with no vendor fix available:
> **Admin Menu Groups plugin CVSS 5.9 Β· No update available
Reviewing the source turned up the reported XSS plus several related issues in the same code paths. All are
fixed here. Functionality is unchanged and existing settings are preserved β this is a drop-in replacement.
## What was fixed
| Severity | Issue | Where |
|---|---|---|
| High | **Stored XSS** β group names, icons, slugs and CSS classes printed into the settings screen with no escaping (~10 sinks). A saved group name executed script for anyone opening the page. | `settings.php` |
| High | **XSS in the admin menu** β an icon value concatenated into `` unescaped. Rendered on *every* wp-admin page, not just the settings screen. | `admin-menu.php` |
| High | **Broken access control + CSRF** β `?amg_hard_reset` deleted all plugin settings with no capability check and no nonce, for any logged-in user. | `admin-menu.php` |
| Medium | **No input sanitisation** β `register_setting()` had no `sanitize_callback`, so the submitted JSON was stored verbatim. | `settings.php` |
| Medium | **DOM XSS** β the "Add Group" row was built by concatenating the typed name into an HTML string. | `js/settings.js` |
| Low | **CSS `url()` injection** in the base64 SVG icon branch (entities re-decode inside a `style` attribute). | `admin-menu.php` |
| Low | Missing `ABSPATH` guards; undefined index notices; missing capability check on the settings callback. | all |
Defence in depth: the configuration is sanitised both **on save** and **on read**, so a site whose option row
was already poisoned while running a vulnerable version is cleaned up on the next page load rather than
staying exploitable until the settings happen to be re-saved.
### Reset behaviour changed
`?amg_hard_reset` no longer works as a bare query string β that was the access-control bug. Use the
**Reset all settings** link at the bottom of the settings page, which carries the required nonce.
`?amg_reset` is unchanged. It only skips menu reorganisation for the current request, stores nothing, and
remains the way to reach the settings page if you have hidden its menu item.
## Installation
Replace the existing `admin-menu-groups` folder in `wp-content/plugins/`. The folder name and the
`amg_options` option name are deliberately unchanged, so saved groups and menu order carry over with no
migration step.
The plugin declares `Update URI: false`. Without it, WordPress would see the abandoned wordpress.org
package at the same slug and offer to "update" this fork back to the vulnerable release.
## Requirements
- WordPress 5.8+ (for `Update URI` support)
- PHP 7.0+
## License
GPLv2 or later, inherited from the original plugin. Original work Β© Chaim Chaikin.