The vulnerability lies in the way the ibexa/fieldtype-richtext package handles the rendering of custom tags within the CKEditor instance. The security advisory points to an XSS vulnerability in the 'acronym' custom tag, but the patch reveals the issue is more general, affecting both block-level and inline-level custom tags.
The analysis of the patch commit 33590a1f2e29849981acfe125906a558fe9b60c3 shows modifications to two key files:
src/bundle/Resources/public/js/CKEditor/custom-tags/block-custom-tag/custom-tag-editing.js
src/bundle/Resources/public/js/CKEditor/custom-tags/inline-custom-tag/inline-custom-tag-editing.js
In both files, the init methods of the IbexaCustomTagEditing and IbexaInlineCustomTagEditing classes define downcast converters. These converters are responsible for transforming the editor's data model into the HTML that is displayed in the editor. The vulnerable code was located inside these converters.
The root cause of the XSS vulnerability was the unsafe construction of HTML strings using innerHTML. The code iterated over the attributes of a custom tag and concatenated the attribute names and values into an HTML string. Crucially, this user-controllable data was not properly sanitized or escaped.
- In
IbexaInlineCustomTagEditing, both the attribute name and value were used raw.
- In
IbexaCustomTagEditing, there was an attempt to escape the attribute value, but it was insufficient, and the attribute name was still used raw.
An attacker could exploit this by creating a piece of content with a specially crafted custom tag, for example, using an attribute name like onmouseover='alert(1)'. When this content is loaded in the rich text editor, the malicious JavaScript would be rendered as part of the editor's view and executed.
The patch addresses this by introducing explicit escaping using escapeHTML for values and escapeHTMLAttribute for attribute names before they are included in the generated HTML. This ensures that any potentially malicious content is rendered as inert text rather than being executed.