The Grav Form plugin (getgrav/grav-plugin-form) versions 8.0.6 through 9.1.19 select the reCAPTCHA version to validate based solely on which response field key is present in the submitted payload. On a site configured for reCAPTCHA v3, an anonymous attacker can place their v3 token under the v2 field name (g-recaptcha-response instead of token), causing validation to use the v2 branch, which never applies the score threshold or verifies the expected action. This results in a complete bypass of reCAPTCHA v3 bot protection. The issue is fixed in version 9.1.20.
Grav Admin before 2.0.20 fails to sanitize output from marked.parse() before injecting it into the DOM via Svelte's {@html} directive in MarkdownEditor and MarkdownModal components. Attackers can inject javascript: URI schemes in plugin or theme changelogs to execute arbitrary code in authenticated admin sessions without requiring site access.
Grav Admin (getgrav/grav-plugin-admin2) versions <= 2.0.19 contain a stored cross-site scripting vulnerability in the tHtml() function (src/lib/stores/i18n.svelte.ts), which substitutes untrusted parameters such as usernames into translation templates before parsing the result as markdown. Grav's server-side username validation (DataUser::isValidUsername) blocks filesystem-dangerous characters but not <, >, ", or ', allowing an attacker to register a username containing an HTML payload. When an administrator views a UI surface that renders the username through tHtml()—such as the two-factor force-disable confirmation prompt or the 'page is locked' editor notice—the payload executes in their authenticated session. Fixed in 2.0.21.
Grav Shortcode Core versions before 6.2.5 contain stored cross-site scripting (XSS) vulnerabilities in the [lorem] tag parameter and [details] summary parameter. These parameters are rendered without proper escaping, allowing attackers with page-edit access to inject arbitrary HTML and JavaScript. This malicious code executes in the browsers of all visitors to the affected pages, including administrators.
Grav versions 2.0.0 through 2.0.17 fail to apply save-time XSS detection to modular pages, allowing authenticated page editors to store Twig-assembled XSS payloads. Attackers with page-edit rights can create modular pages with malicious Twig code that executes in visitor browsers when the parent page is rendered, including in administrator sessions.
CVE-2026-80204 is a critical authorization vulnerability in the Grav API plugin (getgrav/grav-plugin-api) before version 1.0.18. The flaw occurs because the injectSecurityTab() function in BlueprintController does not enforce API-key scope restrictions when determining if a page's security permissions section is editable. This allows an attacker with a scoped API key to potentially view and edit page permission fields beyond their granted scope. The full impact on write operations has not been confirmed.
CVE-2026-80203 is a critical authorization vulnerability in the getgrav/grav-plugin-api plugin before version 1.0.18. The flaw arises because the requireNotSuperTarget() function in UsersController.php incorrectly checks super-admin privileges based on the acting account rather than the API key's scope. This allows an API key with limited scope but belonging to a super-admin account to perform unauthorized actions against other super-admin accounts, such as disabling two-factor authentication, deleting avatars, creating new API keys under another identity, or deleting existing API keys.
Grav versions prior to 2.0.16 have a vulnerability in the Twig sandbox configuration where the default denylist is incomplete. This allows attackers with page-edit permissions to access sensitive system configuration secrets via Twig template functions like config.get() or config.toArray() when config_access is enabled.
Grav versions before 2.0.16 have a vulnerability where sandboxed Twig templates can access sensitive User fields without proper filtering. This allows attackers with page-edit permissions to retrieve hashed passwords and 2FA secrets, potentially enabling offline password cracking and authentication bypass.
CVE-2026-75574 is a high-severity vulnerability in the Grav Email plugin before version 4.2.2. It allows an authenticated user with limited API permissions to execute arbitrary operating system commands via unsandboxed Twig template rendering in email action parameters. This occurs when a Twig expression is placed in the email body parameter, published, and the form is submitted.
Grav CMS versions prior to 2.0.16 have an origin validation bypass vulnerability in the Uri::referrer() and Pages::referrerRoute() methods. These methods validate the Referer header using an unanchored string prefix match without a trailing delimiter, allowing an attacker controlling a domain that starts with the victim site's origin to bypass the Referer-based origin check. This vulnerability is critical with a CVSS score of 9.3.
Grav CMS versions before 2.0.16 have a timing vulnerability in the CSRF nonce validation function Utils::verifyNonce(). The vulnerability arises because the function uses a non-constant-time string comparison operator (===) instead of a constant-time function like hash_equals(). This allows attackers to measure response timing differences and recover valid nonce values byte-by-byte, weakening the intended CSRF protection.
CVE-2026-72700 is a timing discrepancy vulnerability in the getgrav/grav-plugin-login Composer plugin before version 3.9.1. The plugin compares password reset and account activation tokens using a non-constant-time string comparison instead of a timing-safe function, which could allow an attacker to infer valid tokens by measuring response times. The token submission endpoint also lacks rate limiting, increasing the theoretical risk. However, the vendor rates the practical exploitability as low, and no confirmed network exploit has been demonstrated.
The Grav Login plugin before version 3.9.1 has an email address enumeration vulnerability. The register() method throws a distinct exception when an email is already registered, allowing attackers to confirm existing accounts. There is no rate limiting on the registration endpoint, enabling automated enumeration attacks.
Grav CMS versions before 2.0.16 contain a vulnerability that allows content editors with page-content edit access to read sensitive configuration data. This occurs because the system, site, and theme configuration arrays are not properly filtered in sandboxed Twig renders, enabling unauthorized access to secrets such as cache credentials via dot notation in Twig templates. The vulnerability bypasses config_denied_paths restrictions.
Grav CMS versions before 2.0.16 have a path traversal vulnerability in the media_directory() Twig function. This flaw allows authenticated users with page authoring privileges to supply arbitrary filesystem paths and read files outside the intended directory scope, limited to files matching configured media extensions accessible by the web server process.
Grav CMS versions before 2.0.16 have a vulnerability in the Scheduler component where symlink following is improperly handled during lock file creation. This allows local attackers to create symbolic links at predictable lock file paths in a world-writable temporary directory, causing the scheduled job to overwrite arbitrary files writable by the web server process with the job ID string.
Grav versions before 2.0.16 have a path traversal vulnerability in the MediaUploadTrait::deleteFile() function. Authenticated users with media management permissions can delete arbitrary files outside the intended media directory by using directory traversal sequences in filenames. The vulnerability arises because only the basename of the filename is validated, while directory paths containing '../' sequences are not properly checked before being passed to the unlink() function.
Grav Login plugin versions before 1.0.16 contain an authorization flaw in the onApiUserListRowAction unlock handler. This flaw allows an attacker with api.users.write permission to reset login lockout counters on admin.super accounts, effectively removing brute-force protection from these high-privilege accounts without needing equivalent permissions.
Grav versions prior to 3.9.2 contain a vulnerability in the sendInvitationEmail() function where untrusted Host headers are not properly validated. This allows attackers to manipulate the Host header to create invitation links that redirect users to attacker-controlled domains. The require_trusted_host protection only applies to password reset flows and does not mitigate this issue for invitation links.