GHSA-269c-h76q-8cxw: XSS

Published Sep 17, 2026
·
Updated

Summary

A page editor without admin.super can place an event handler after a > inside a quoted attribute. Grav accepts and stores the page, then executes the handler in the application origin when a visitor opens it.

Details

Security::detectXss() (system/src/Grav/Common/Security.php:253) anchors the onevents scan at < and uses [^>]?, which cannot cross the first literal >. When that character is inside a quoted value, the browser keeps the tag open and parses the later onerror attribute, so the detector and browser disagree. AdminController::savePage() relies on this detector when saving content from page editors outside the admin.super whitelist.

PoC

I reproduced this with getgrav/grav 2.0.11 (ad9709f865b09b68798fb1ac375b484a8cc1d892), Admin 1.10.52, and Quark 2 1.1.4.

1. Sign in as a user with admin.login and admin.pages, but without admin.super. 2. Create or edit /xsstest and save this page body:

html <img src=x title=">" onerror=alert(document.domain)>

3. Open /xsstest in a private browser window.

The save succeeds and the visitor sees an alert containing the site domain. With the body changed to <img src=x onerror=alert(1)>, the same endpoint rejects it with XSS issue detected and does not store it.

Impact

A page editor can execute JavaScript in the origin of every user who views the stored page, including unauthenticated visitors.

Anticipated objection and response

Although the detectXss() docblock describes it as a heuristic that cannot catch every XSS, this check is the storage-time boundary for page editors outside the default security.xsswhitelist of admin.super. The same endpoint rejects a plain handler but accepts this executable form, allowing a lower-trust editor to cross the boundary the check is intended to enforce.

Suggested fix

Prefer an HTML tokenizer or sanitizer that rejects event-handler attributes on parsed elements. If the existing tripwire remains, make its tag scan quote-aware instead of treating every > as a boundary. Add double-quoted and single-quoted regression cases plus the rejected plain-handler control.

Affected Software

1 affected componentFixes available
composer/getgrav/grav>=1.5.2<=2.0.12
2.0.13

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/getgrav/grav to a version that resolves this vulnerability.

    Fixed in 2.0.13
  2. Upgrade

    Upgrade getgrav/grav to a version that resolves this vulnerability.

    Fixed in 2.0.11Patch ad9709f865b09b68798fb1ac375b484a8cc1d892
  3. Configuration

    Modify `Security::detectXss()` so the `on_events` detection is quote-aware (so `>` characters inside quoted attributes don’t prematurely terminate the match). Specifically, avoid the current `on_events` regex behavior anchored at `<` using `[^>]*?` that cannot cross the first literal `>`.

    Grav Admin (AdminController::savePage / Security::detectXss) Security::detectXss() on_events scan (quote-aware tokenization) = Update the tag scan to be quote-aware so it does not treat every `>` as a boundary when inside quoted attribute values
  4. Compensating control

    Prefer an HTML tokenizer or sanitizer at storage-time that rejects event-handler attributes (e.g., attributes like `onerror`) on parsed elements, rather than relying on a heuristic regex boundary check.

Event History

Sep 17, 2026
Advisory Published
via GitHub·05:28 PM
Data Sourced
via GitHub·05:28 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What level of access does an attacker need?

The attacker needs an authenticated account with admin.login and admin.pages permissions. The account does not need the admin.super privilege.

2

Who is exposed when malicious content is saved?

Any visitor who opens the affected page can trigger the stored handler. The handler executes in the application origin, so the impact applies to the visitor's session in that origin.

3

What content pattern bypasses the relevant save-time check?

A literal > placed inside a quoted HTML attribute can cause the detector to stop scanning before a later event-handler attribute. The browser can still treat that later attribute, such as onerror, as part of the open tag.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203