Aller au contenu principal
HDWSec
Medium CVE-2026-72821

Grav Form Plugin: Stored Cross-Site Scripting in Radio and Toggle Option Labels

Sévérité
Medium
Score CVSS
5.4CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Identifiants CVE
CVE-2026-72821
Éditeur
Grav
Produit
Grav CMS (grav-plugin-form, radio and toggle field templates)
Versions affectées
grav-plugin-form 9.1.14 and earlier
Version corrigée
9.1.15
Type de vulnérabilité
Stored Cross-site Scripting (CWE-79) through an incomplete fix of CVE-2026-42842
Chercheurs
Jean-Jamil KHALIFÉ

Presentation

Grav is an open-source flat-file PHP content management system developed by Trilby Media. Its Form plugin is the official form builder: a form is declared in page frontmatter or in a blueprint as a list of fields, and each field type is rendered by its own Twig template shipped with the plugin.

HDW Sec found that two of those templates print option labels through the Twig |raw filter, so an author who controls a form’s option labels stores markup that executes in the browser of everyone who later views the form. The two sinks are siblings of a select option-text flaw that had already been reported and fixed, and that earlier fix did not cover them.

Issue(s)

  • The option-rendering templates disagree on how they emit an option label. The checkboxes template escapes it, while radio (templates/forms/fields/radio/radio.html.twig:18) and toggle (templates/forms/fields/toggle/toggle.html.twig:5 and :49) pass it through |raw.
  • All three iterate the same field.options structure, so the same attacker-controlled value reaches an escaped sink in one template and an unescaped one in the other two.
  • The select variant of this flaw was fixed in CVE-2026-42842. That fix dropped |raw from select.html.twig only, leaving radio and toggle exploitable: an incomplete fix rather than a new sink.
  • Reproduced live on Grav 2.0.12 with grav-plugin-form 9.1.14. A page defining radio, toggle and checkboxes fields whose option labels all carry the same <img src=x onerror=...> payload serves the radio and toggle labels as live elements, while the checkboxes label on the same page is escaped. That differential isolates the defect to the two templates.
  • The payload runs for front-end visitors of the public page and for any higher-privileged administrator who previews or opens it, which crosses the author to visitor and author to administrator trust boundary. Grav rated it moderate, 5.4.
  • One honest limitation: in the lab the option labels came from page-author frontmatter, which is that author’s own input. A lower-privileged dynamic option provider feeding the same labels was not independently wired, so the demonstrated boundary is author to viewer rather than anonymous to author.

References

Notre R&D traque les vulnérabilités.

Recherche de 0-day, reverse engineering, divulgation coordonnée : découvrez notre pôle R&D.