Skip to content

Cross-Site Scripting (XSS) via postMessage Handler

Moderate
SebastianStehle published GHSA-7q4f-fprr-5jw8 Nov 7, 2023

Package

No package listed

Affected versions

7.8.2

Patched versions

7.9.0

Description

Summary

The missing origin verification in a postMessage handler introduces a Cross-Site Scripting (XSS) vulnerability.

Details

The editor-sdk.js file defines three different class-like functions, which employ a global message event listener: SquidexSidebar, SquidexWidget, and SquidexFormField.

function SquidexFormField() {
  // ...
 window.addEventListener('message', eventListener, false);
}

The registered event listener takes some action based on the type of the received message. For example, when the SquidexFormField receives a message with the type valueChanged, the value property is updated, and the function raiseValueChanged is called:

    function eventListener(event) {
        if (event.source !== window) {
            var type = event.data.type;
            console.log('Received Message: ' + type);
            if (...) {
                // ...
            } else if (type === 'valueChanged') {
                value = event.data.value;
                raiseValueChanged();
            }
     // ...

The raiseValueChanged function invokes the valueHandler callback function, if defined:

    function raiseValueChanged() {
        if (valueHandler) {
            valueHandler(value);
        }
    }


This callback function can be registered via the onValueChanged function:

        /**
     * Register an function that is called whenever the value of the field has changed.
     *
     * @param {function} callback: The callback to invoke. Argument 1: Field value (any).
     */
        onValueChanged: function (callback) {
            if (!isFunction(callback)) {
                return;
            }
            valueHandler = callback;
            raiseValueChanged();
        },

The SquidexFormField class is for example used in the editor-editorjs.html file, which can be accessed via the public wwwroot folder. It uses the onValueChanged method to register a callback function, which passes the value provided from the message event to the editor.render function:

<!DOCTYPE html>
<html>
...
    <script>
        var field = new SquidexFormField();
        var editor = new EditorJS({
            ...
            onReady: function () {
                field.onValueChanged(function (value) {
                    if (value) {
                        editor.render(value);
                    }
                });
                ...
    </script>
</body>
</html>

The editor.render function used here is part of the editorjs npm package. Passing an attacker-controlled value to this function introduces a Cross-Site Scripting (XSS) vulnerability. Since the registered message event listener in editor-sdk.js does not verify the origin of the received message, an attacker can include the editor-editorjs.html page in an iframe and send a message to it in order to trigger the XSS vulnerability.
Please note that this is just one example of turning this into an XSS vulnerability. The root cause of this vulnerability is the missing origin checks of the message event listeners.

Impact

The vulnerability allows an attacker to execute arbitrary JavaScript code in the context of a user authenticated to Squidex by tricking them into visiting a malicious website.

Severity

Moderate
6.8
/ 10

CVSS base metrics

Attack vector
Adjacent
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
High
Integrity
Low
Availability
Low
CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:L

CVE ID

CVE-2023-46252