VYPR
Medium severity5.4OSV Advisory· Published Jul 31, 2024· Updated Apr 15, 2026

CVE-2024-39318

CVE-2024-39318

Description

The Ibexa Admin UI Bundle contains all the necessary parts to run the Ibexa DXP Back Office interface. The file upload widget is vulnerable to XSS payloads in filenames. Access permission to upload files is required. As such, in most cases only authenticated editors and administrators will have the required permission. It is not persistent, i.e. the payload is only executed during the upload. In effect, an attacker will have to trick an editor/administrator into uploading a strangely named file.

AI Insight

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

Ibexa DXP file upload widget has a DOM-based XSS vulnerability where filenames are not sanitized, enabling attackers to trick editors into uploading malicious files.

Description

The Ibexa DXP Admin UI Bundle includes a file upload widget that is vulnerable to a DOM-based Cross-Site Scripting (XSS) attack due to unsanitized filenames [1][4]. The root cause is that the JavaScript code directly sets the innerHTML and title attributes of preview elements using the raw filename from the file input, without escaping HTML entities [2][3]. The fix, as seen in merged commits, introduces the escapeHTML helper to properly sanitize the filename before inserting it into the DOM [2][3].

Exploitation

An attacker must be able to upload files to the system, which typically requires authenticated access as an editor or administrator [1][4]. The vulnerability is triggered only during the upload preview phase—the payload is not persistent and executes only when the file is selected for upload [1][4]. Therefore, the attacker would need to trick a privileged user into uploading a file with a maliciously crafted filename containing JavaScript payloads [4].

Impact

Successful exploitation leads to DOM-based XSS execution in the context of the victim's browser session [1][4]. This could allow the attacker to perform actions on behalf of the victim, access sensitive data displayed in the interface, or escalate privileges within the application, depending on the victim's permissions [1].

Mitigation

Ibexa has released patched versions: Ibexa DXP v3.3.39 (ezsystems/ezplatform-admin-ui) and v4.6.9 (ibexa/admin-ui) [4]. Users should update to these versions or later to remediate the vulnerability [1][4]. No workarounds are documented in the provided references.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
ibexa/admin-uiPackagist
>= 4.6.0-beta1, < 4.6.94.6.9

Affected products

3

Patches

3
7a9f991b200f

Merge commit from fork

https://github.com/ezsystems/ezplatform-admin-uiDariusz SzutJul 31, 2024via ghsa
3 files changed · +16 10
  • src/bundle/Resources/public/js/scripts/fieldType/ezbinaryfile.js+6 4 modified
    @@ -1,4 +1,4 @@
    -(function(global, doc, eZ) {
    +(function (global, doc, eZ) {
         const SELECTOR_FIELD = '.ez-field-edit--ezbinaryfile';
         const SELECTOR_LABEL_WRAPPER = '.ez-field-edit__label-wrapper';
         const SELECTOR_FILESIZE_NOTICE = '.ez-data-source__message--filesize';
    @@ -15,9 +15,11 @@
                 const sizeContainer = preview.querySelector('.ez-field-edit-preview__file-size');
                 const files = [].slice.call(event.target.files);
                 const fileSize = this.formatFileSize(files[0].size);
    +            const { escapeHTML } = eZ.helpers.text;
    +            const fileName = escapeHTML(files[0].name);
     
    -            nameContainer.innerHTML = files[0].name;
    -            nameContainer.title = files[0].name;
    +            nameContainer.innerHTML = fileName;
    +            nameContainer.title = fileName;
                 sizeContainer.innerHTML = fileSize;
                 sizeContainer.title = fileSize;
     
    @@ -63,5 +65,5 @@
             previewField.init();
     
             eZ.addConfig('fieldTypeValidators', [validator], true);
    -    })
    +    });
     })(window, window.document, window.eZ);
    
  • src/bundle/Resources/public/js/scripts/fieldType/ezimage.js+5 3 modified
    @@ -1,4 +1,4 @@
    -(function(global, doc, eZ) {
    +(function (global, doc, eZ) {
         const SELECTOR_FIELD = '.ez-field-edit--ezimage';
         const SELECTOR_INPUT_FILE = 'input[type="file"]';
         const SELECTOR_LABEL_WRAPPER = '.ez-field-edit__label-wrapper';
    @@ -36,11 +36,13 @@
                 const sizeContainer = preview.querySelector('.ez-field-edit-preview__file-size');
                 const files = [].slice.call(event.target.files);
                 const fileSize = this.formatFileSize(files[0].size);
    +            const { escapeHTML } = eZ.helpers.text;
    +            const fileName = escapeHTML(files[0].name);
     
                 this.getImageUrl(files[0], (url) => image.setAttribute('src', url));
     
    -            nameContainer.innerHTML = files[0].name;
    -            nameContainer.title = files[0].name;
    +            nameContainer.innerHTML = fileName;
    +            nameContainer.title = fileName;
                 sizeContainer.innerHTML = fileSize;
                 sizeContainer.title = fileSize;
     
    
  • src/bundle/Resources/public/js/scripts/fieldType/ezmedia.js+5 3 modified
    @@ -1,4 +1,4 @@
    -(function(global, doc, eZ) {
    +(function (global, doc, eZ) {
         const SELECTOR_FIELD = '.ez-field-edit--ezmedia';
         const SELECTOR_PREVIEW = '.ez-field-edit__preview';
         const SELECTOR_MEDIA = '.ez-field-edit-preview__media';
    @@ -62,9 +62,11 @@
                 const sizeContainer = preview.querySelector('.ez-field-edit-preview__file-size');
                 const files = [].slice.call(event.target.files);
                 const fileSize = this.formatFileSize(files[0].size);
    +            const { escapeHTML } = eZ.helpers.text;
    +            const fileName = escapeHTML(files[0].name);
     
    -            nameContainer.innerHTML = files[0].name;
    -            nameContainer.title = files[0].name;
    +            nameContainer.innerHTML = fileName;
    +            nameContainer.title = fileName;
                 sizeContainer.innerHTML = fileSize;
                 sizeContainer.title = fileSize;
     
    
8dc413fad104

Merge branch '2.3' of ezsystems/ezplatform-admin-ui into 4.6 (#1311)

https://github.com/ibexa/admin-uiDariusz SzutJul 31, 2024via ghsa
3 files changed · +12 6
  • src/bundle/Resources/public/js/scripts/fieldType/ezbinaryfile.js+4 2 modified
    @@ -13,9 +13,11 @@
                 const sizeContainer = preview.querySelector('.ibexa-field-edit-preview__file-size');
                 const files = [].slice.call(event.target.files);
                 const fileSize = this.formatFileSize(files[0].size);
    +            const { escapeHTML } = ibexa.helpers.text;
    +            const fileName = escapeHTML(files[0].name);
     
    -            nameContainer.innerHTML = files[0].name;
    -            nameContainer.title = files[0].name;
    +            nameContainer.innerHTML = fileName;
    +            nameContainer.title = fileName;
                 sizeContainer.innerHTML = fileSize;
                 sizeContainer.title = fileSize;
     
    
  • src/bundle/Resources/public/js/scripts/fieldType/ezimage.js+4 2 modified
    @@ -34,6 +34,8 @@
                 const sizeContainer = preview.querySelector('.ibexa-field-edit-preview__file-size');
                 const files = [].slice.call(event.target.files);
                 const fileSize = this.formatFileSize(files[0].size);
    +            const { escapeHTML } = ibexa.helpers.text;
    +            const fileName = escapeHTML(files[0].name);
     
                 this.getImageUrl(files[0], (url) => {
                     const image = new Image();
    @@ -60,8 +62,8 @@
                     imageNode.setAttribute('src', url);
                 });
     
    -            nameContainer.innerHTML = files[0].name;
    -            nameContainer.title = files[0].name;
    +            nameContainer.innerHTML = fileName;
    +            nameContainer.title = fileName;
                 sizeContainer.innerHTML = fileSize;
                 sizeContainer.title = fileSize;
     
    
  • src/bundle/Resources/public/js/scripts/fieldType/ezmedia.js+4 2 modified
    @@ -52,9 +52,11 @@
                 const sizeContainer = preview.querySelector('.ibexa-field-edit-preview__file-size');
                 const files = [].slice.call(event.target.files);
                 const fileSize = this.formatFileSize(files[0].size);
    +            const { escapeHTML } = ibexa.helpers.text;
    +            const fileName = escapeHTML(files[0].name);
     
    -            nameContainer.innerHTML = files[0].name;
    -            nameContainer.title = files[0].name;
    +            nameContainer.innerHTML = fileName;
    +            nameContainer.title = fileName;
                 sizeContainer.innerHTML = fileSize;
                 sizeContainer.title = fileSize;
     
    

Vulnerability mechanics

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

References

7

News mentions

0

No linked articles in our index yet.