VYPR
Unrated severityNVD Advisory· Published Jun 21, 2026

Craft CMS - Stored XSS in Table Field via Row Heading Column Type

CVE-2026-56383

Description

Craft CMS contains a stored cross-site scripting (XSS) vulnerability in the editableTable.twig component when using the 'Row Heading' column type. The application fails to sanitize input within row heading default values, allowing an attacker with an administrator account (with allowAdminChanges enabled) to inject arbitrary JavaScript that executes when another user views a page containing the affected table field. Affected versions are >= 4.5.0-beta.1 through 4.16.18 and >= 5.0.0-RC1 through 5.8.22; fixed in 4.16.19 and 5.8.23.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Affected products

2
  • Craftcms/CMSinferred2 versions
    >=5.0.0-RC1,<=5.8.22+ 1 more
    • (no CPE)range: >=5.0.0-RC1,<=5.8.22
    • (no CPE)range: >= 4.5.0-beta.1 through 4.16.18 and >= 5.0.0-RC1 through 5.8.22

Patches

Vulnerability mechanics

Root cause

"The application fails to sanitize input within row heading default values in the editableTable.twig component, allowing stored XSS."

Attack vector

An attacker with an administrator account (and `allowAdminChanges` enabled) creates or edits a Table field, sets a column type to **Row Heading**, and inserts a malicious payload such as `<img src=x onerror='alert("XSS")'>` into the **Default Values** row heading. When another user views any page that renders that table field (e.g., a user profile), the unsanitized heading is output in the browser, causing the injected script to execute [ref_id=1]. The vulnerability is a stored cross-site scripting (XSS) weakness because the application fails to sanitize input within row heading default values [ref_id=1].

What the fix does

The patch [ref_id=2] removes the `Html::encode()` call from `_normalizeCellValue()` for the `'heading'` case and instead moves the encoding into `_getInputHtml()`, where the value is wrapped as `['value' => Html::encode($row[$colId]), ...]` only when the column type is `'heading'`. This ensures that row heading values are HTML-encoded at the point of output rather than during normalization, preventing stored XSS while preserving the original value in the database.

Preconditions

  • authThe attacker must have an administrator account on the Craft CMS instance.
  • configThe `allowAdminChanges` config setting must be enabled (which is against the vendor's security recommendations for production).
  • inputThe attacker must create or edit a Table field with a column type set to 'Row Heading' and insert a malicious payload into the default values.

Reproduction

Navigate to Settings → Fields and create a new field with Type: Table. Add a Column Heading and set Column Type to **Row Heading**. In the Default Values section, add a row with the payload `<img src=x onerror='alert("XSS")'>`. Enable **Static Rows**. Use the field in any object (e.g., user profile fields) and then visit any user's profile to observe the XSS execution [ref_id=1].

Generated on Jun 22, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.