From 6b4aa0a6b01893ad132f81c8974d54fe25ebe00d Mon Sep 17 00:00:00 2001 From: mnhnam-axonivy Date: Mon, 16 Dec 2024 10:32:07 +0700 Subject: [PATCH 1/3] IVYPORTAL-18029 High - Client-side cross-site scripting - Fixed security check --- .../portal/webContent/resources/js/iframe-task-template.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js b/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js index 7e32a706de4..02d1c0b63f7 100644 --- a/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js +++ b/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js @@ -1,15 +1,14 @@ var invalidIFrameSrcPath = false; let taskUrl = new URLSearchParams(window.location.search).get("taskUrl"); -let updateIframeSrc = (newSrc) => { - getPortalIframe().src = newSrc; -} + if (taskUrl){ if(taskUrl.endsWith('blank')){ window.history.back(document.referrer); } - updateIframeSrc(taskUrl) + getPortalIframe().src = taskUrl; } + loadIframe(false); var recheckFrameTimer; function loadIframe(recheckIndicator) { From c8474f3527c145dfb73b299376350a8b955a8899 Mon Sep 17 00:00:00 2001 From: mnhnam-axonivy Date: Mon, 16 Dec 2024 10:40:42 +0700 Subject: [PATCH 2/3] IVYPORTAL-18029 High - Client-side cross-site scripting - Try to fix Client-side cross-site scripting --- .../portal/webContent/resources/js/iframe-task-template.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js b/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js index 02d1c0b63f7..6eb27d0635e 100644 --- a/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js +++ b/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js @@ -6,7 +6,7 @@ if (taskUrl){ if(taskUrl.endsWith('blank')){ window.history.back(document.referrer); } - getPortalIframe().src = taskUrl; + getPortalIframe().src = new URLSearchParams(window.location.search).get("taskUrl"); } loadIframe(false); From 960f08804fd6b55a6577517685fa9c0abc1347f6 Mon Sep 17 00:00:00 2001 From: mnhnam-axonivy Date: Mon, 16 Dec 2024 14:02:09 +0700 Subject: [PATCH 3/3] IVYPORTAL-18029 High - Client-side cross-site scripting - Apply new approach --- .../generic/bean/IFrameTaskTemplateBean.java | 7 +++ .../restricted/IFrameTaskTemplate.xhtml | 49 ++++++++++++------- .../resources/js/iframe-task-template.js | 10 ---- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java index c7b6b99bcd2..af864d25651 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java @@ -54,6 +54,7 @@ public class IFrameTaskTemplateBean extends AbstractTaskTemplateBean implements public static final String PORTAL_GROWL_MESSGE_PARAM = "portalGrowlMessage"; private static final String DEFAULT_TASK_ICON = "si si-task-list-edit"; private static final String TASK_ICON = "taskIcon"; + private static final String TASK_URL = "taskUrl"; private int currentProcessStep; private List processSteps; @@ -74,6 +75,12 @@ public class IFrameTaskTemplateBean extends AbstractTaskTemplateBean implements private Long caseId = null; + public String getTaskUrl() { + return Optional.ofNullable(FacesContext.getCurrentInstance() + .getExternalContext().getRequestParameterMap().get(TASK_URL)) + .orElse(StringUtils.EMPTY); + } + public void useTaskInIFrame() { keepOverridePortalGrowl(); Map requestParamMap = getRequestParameterMap(); diff --git a/AxonIvyPortal/portal/webContent/layouts/restricted/IFrameTaskTemplate.xhtml b/AxonIvyPortal/portal/webContent/layouts/restricted/IFrameTaskTemplate.xhtml index c9cda06739d..7b521bc862c 100644 --- a/AxonIvyPortal/portal/webContent/layouts/restricted/IFrameTaskTemplate.xhtml +++ b/AxonIvyPortal/portal/webContent/layouts/restricted/IFrameTaskTemplate.xhtml @@ -70,24 +70,24 @@ **2. JavaScript-Based Configuration:** Example: + window.taskName = "Approve Investment"; + window.taskIcon = "si si-bulb"; + window.isHideTaskName = false; + window.caseId = "123456"; + window.isHideCaseInfo = false; + window.currentProcessStep = 0; + window.processSteps = ["Create Investment Request", "Approve Investment Request"]; + // Convert Java List of steps to JSON format if needed: + window.processSteps = #{portalComponentUtilsBean.convertToJSON(data.steps)}; + window.isShowAllSteps = true; + window.processChainDirection = "VERTICAL"; + window.processChainShape = "LINE"; + window.isHideTaskAction = false; + window.isWorkingOnATask = false; + window.announcementInvisible = false; + window.isCardFrame = true; + window.viewName = "TASK_DETAIL"; + --> @@ -113,6 +113,19 @@ + diff --git a/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js b/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js index 6eb27d0635e..46a55531bc3 100644 --- a/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js +++ b/AxonIvyPortal/portal/webContent/resources/js/iframe-task-template.js @@ -1,15 +1,5 @@ var invalidIFrameSrcPath = false; -let taskUrl = new URLSearchParams(window.location.search).get("taskUrl"); - -if (taskUrl){ - if(taskUrl.endsWith('blank')){ - window.history.back(document.referrer); - } - getPortalIframe().src = new URLSearchParams(window.location.search).get("taskUrl"); -} - -loadIframe(false); var recheckFrameTimer; function loadIframe(recheckIndicator) { var iframe = getPortalIframe();