From 6cdd69d31d6bf3caa7f40ec55eb317e4e528ad28 Mon Sep 17 00:00:00 2001 From: pjeanjean Date: Tue, 16 Jan 2024 15:10:35 +0100 Subject: [PATCH] XWIKI-19611: Improve filename escaping in attachment upload * Use escapeHTML() when displaying filenames in upload.js * Add a test in AttachmentIT to check for proper HTML escaping during upload (cherry picked from commit 910a5018a50039e8b24556573dfe342f143ef949) --- .../flamingo/test/docker/AttachmentIT.java | 19 +++++++++++++++++++ .../EscapedAttachment.txt | 1 + .../resources/uicomponents/widgets/upload.js | 11 ++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/resources/AttachmentIT/EscapedAttachment.txt diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/AttachmentIT.java b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/AttachmentIT.java index aba117b4a38d..ab4f0096992a 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/AttachmentIT.java +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/AttachmentIT.java @@ -65,6 +65,8 @@ class AttachmentIT private static final String SECOND_ATTACHMENT = "SmallAttachment2.txt"; + private static final String ESCAPED_ATTACHMENT = "EscapedAttachment.txt"; + private static final String IMAGE_ATTACHMENT = "image.gif"; private static final String SMALL_SIZE_ATTACHMENT = "SmallSizeAttachment.png"; @@ -447,6 +449,23 @@ void deleteAttachmentWithSpecialChar(TestUtils setup, TestReference testReferenc basePage.getXWikiMessageContent()); } + @Test + @Order(9) + void checkEscapingInAttachmentName(TestUtils setup, TestReference testReference, + TestConfiguration testConfiguration) + { + setup.loginAsSuperAdmin(); + setup.createPage(testReference, "Empty content"); + AttachmentsPane attachmentsPane = new AttachmentsViewPage().openAttachmentsDocExtraPane(); + + attachmentsPane.setFileToUpload(getFileToUpload(testConfiguration, ESCAPED_ATTACHMENT).getAbsolutePath()); + attachmentsPane.waitForUploadToFinish(ESCAPED_ATTACHMENT); + attachmentsPane.clickHideProgress(); + + assertTrue(attachmentsPane.attachmentExistsByFileName(ESCAPED_ATTACHMENT)); + attachmentsPane.deleteAttachmentByFileByName(ESCAPED_ATTACHMENT); + } + private String getAttachmentsMacroContent(DocumentReference docRef) { StringBuilder sb = new StringBuilder(); diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/resources/AttachmentIT/EscapedAttachment.txt b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/resources/AttachmentIT/EscapedAttachment.txt new file mode 100644 index 000000000000..3cfe87304cd3 --- /dev/null +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/resources/AttachmentIT/EscapedAttachment.txt @@ -0,0 +1 @@ +This is an attachment whose name should be escaped. \ No newline at end of file diff --git a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/upload.js b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/upload.js index adfe41a5f091..7203cb10be14 100644 --- a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/upload.js +++ b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/widgets/upload.js @@ -124,7 +124,7 @@ var XWiki = (function(XWiki) { if (this.options.enableFileInfo) { statusUI.FILE_INFO = UploadUtils.createDiv('file-info'); - (statusUI.FILE_NAME = UploadUtils.createSpan('file-name', this.file.name)).title = this.file.type; + (statusUI.FILE_NAME = UploadUtils.createSpan('file-name', this.file.name.escapeHTML())).title = this.file.type; statusUI.FILE_SIZE = UploadUtils.createSpan('file-size', ' (' + UploadUtils.bytesToSize(this.file.size) + ')'); statusUI.FILE_CANCEL = UploadUtils.createButton("$services.localization.render('core.widgets.html5upload.item.cancel')", this.cancelUpload.bindAsEventListener(this)); // TODO MIME type icon? @@ -295,7 +295,7 @@ var XWiki = (function(XWiki) { this.statusUI.FILE_CANCEL.addClassName('hidden'); } this.formData.input.fire('xwiki:html5upload:message', {content: 'UPLOAD_FINISHING', type: 'inprogress', source: this, - parameters : {name : this.file.name} + parameters : {name : this.file.name.escapeHTML()} }); }, @@ -324,7 +324,7 @@ var XWiki = (function(XWiki) { } } this.formData.input.fire('xwiki:html5upload:message', {content: 'UPLOAD_FINISHED', type: 'done', source: this, - parameters : {name : this.file.name, size : UploadUtils.bytesToSize(this.file.size)} + parameters : {name : this.file.name.escapeHTML(), size : UploadUtils.bytesToSize(this.file.size)} }); this.formData.input.fire('xwiki:html5upload:fileFinished', {source: this}); clearInterval(this.timer); @@ -354,7 +354,8 @@ var XWiki = (function(XWiki) { */ abnormalUploadFinish : function (message) { clearInterval(this.timer); - this.formData.input.fire('xwiki:html5upload:message', {content: message, type: 'error', source: this, parameters : {name : this.file.name}}); + this.formData.input.fire('xwiki:html5upload:message', {content: message, type: 'error', source: this, parameters : + {name : this.file.name.escapeHTML()}}); this.formData.input.fire('xwiki:html5upload:fileFinished', {source: this}); } }); @@ -517,7 +518,7 @@ var XWiki = (function(XWiki) { } } catch (ex) { this.showMessage(ex, 'error', {size : UploadUtils.bytesToSize(this.options && this.options.maxFilesize), - name : file.name, type: file.type + name : file.name.escapeHTML(), type: file.type }); } }