Medium severity6.1NVD Advisory· Published Aug 7, 2017· Updated May 13, 2026
CVE-2017-12647
CVE-2017-12647
Description
XSS exists in Liferay Portal before 7.0 CE GA4 via a Knowledge Base article title.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.liferay.portal:release.portal.bomMaven | < 7.0.3-ga4 | 7.0.3-ga4 |
Affected products
1Patches
436b21590d1caLPS-72090 Sanitize content to prevent XSS
3 files changed · +64 −0
modules/apps/knowledge-base/knowledge-base-service/src/main/java/com/liferay/knowledge/base/service/persistence/impl/KBArticlePersistenceImpl.java+31 −0 modified@@ -30,8 +30,13 @@ import com.liferay.portal.kernel.dao.orm.QueryUtil; import com.liferay.portal.kernel.dao.orm.SQLQuery; import com.liferay.portal.kernel.dao.orm.Session; +import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; +import com.liferay.portal.kernel.sanitizer.Sanitizer; +import com.liferay.portal.kernel.sanitizer.SanitizerException; +import com.liferay.portal.kernel.sanitizer.SanitizerUtil; +import com.liferay.portal.kernel.security.auth.PrincipalThreadLocal; import com.liferay.portal.kernel.security.permission.InlineSQLHelperUtil; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.ServiceContextThreadLocal; @@ -40,6 +45,8 @@ import com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.CharPool; +import com.liferay.portal.kernel.util.ContentTypes; +import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.ReflectionUtil; import com.liferay.portal.kernel.util.SetUtil; @@ -32159,6 +32166,30 @@ public KBArticle updateImpl(KBArticle kbArticle) { } } + long userId = GetterUtil.getLong(PrincipalThreadLocal.getName()); + + if (userId > 0) { + long companyId = kbArticle.getCompanyId(); + + long groupId = kbArticle.getGroupId(); + + long kbArticleId = 0; + + if (!isNew) { + kbArticleId = kbArticle.getPrimaryKey(); + } + + try { + kbArticle.setContent(SanitizerUtil.sanitize(companyId, groupId, + userId, KBArticle.class.getName(), kbArticleId, + ContentTypes.TEXT_HTML, Sanitizer.MODE_ALL, + kbArticle.getContent(), null)); + } + catch (SanitizerException se) { + throw new SystemException(se); + } + } + Session session = null; try {
modules/apps/knowledge-base/knowledge-base-service/src/main/java/com/liferay/knowledge/base/service/persistence/impl/KBTemplatePersistenceImpl.java+31 −0 modified@@ -30,14 +30,21 @@ import com.liferay.portal.kernel.dao.orm.QueryUtil; import com.liferay.portal.kernel.dao.orm.SQLQuery; import com.liferay.portal.kernel.dao.orm.Session; +import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; +import com.liferay.portal.kernel.sanitizer.Sanitizer; +import com.liferay.portal.kernel.sanitizer.SanitizerException; +import com.liferay.portal.kernel.sanitizer.SanitizerUtil; +import com.liferay.portal.kernel.security.auth.PrincipalThreadLocal; import com.liferay.portal.kernel.security.permission.InlineSQLHelperUtil; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.ServiceContextThreadLocal; import com.liferay.portal.kernel.service.persistence.CompanyProvider; import com.liferay.portal.kernel.service.persistence.CompanyProviderWrapper; import com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl; +import com.liferay.portal.kernel.util.ContentTypes; +import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.ReflectionUtil; import com.liferay.portal.kernel.util.SetUtil; @@ -2620,6 +2627,30 @@ public KBTemplate updateImpl(KBTemplate kbTemplate) { } } + long userId = GetterUtil.getLong(PrincipalThreadLocal.getName()); + + if (userId > 0) { + long companyId = kbTemplate.getCompanyId(); + + long groupId = kbTemplate.getGroupId(); + + long kbTemplateId = 0; + + if (!isNew) { + kbTemplateId = kbTemplate.getPrimaryKey(); + } + + try { + kbTemplate.setContent(SanitizerUtil.sanitize(companyId, + groupId, userId, KBTemplate.class.getName(), + kbTemplateId, ContentTypes.TEXT_HTML, + Sanitizer.MODE_ALL, kbTemplate.getContent(), null)); + } + catch (SanitizerException se) { + throw new SystemException(se); + } + } + Session session = null; try {
modules/apps/knowledge-base/knowledge-base-service/src/main/resources/META-INF/portlet-model-hints.xml+2 −0 modified@@ -22,6 +22,7 @@ <field name="urlTitle" type="String" /> <field name="content" type="String"> <hint-collection name="CLOB" /> + <sanitize content-type="text/html" modes="ALL" /> </field> <field name="description" type="String"> <hint-collection name="TEXTAREA" /> @@ -93,6 +94,7 @@ </field> <field name="content" type="String"> <hint-collection name="CLOB" /> + <sanitize content-type="text/html" modes="ALL" /> </field> <field name="lastPublishDate" type="Date" /> </model>
461278bda30eLPS-72090 Fix XSS
27 files changed · +50 −62
modules/apps/foundation/frontend-taglib/frontend-taglib/src/main/resources/META-INF/resources/add_menu/page.jsp+1 −1 modified@@ -48,7 +48,7 @@ String viewMoreURL = (String)request.getAttribute("liferay-frontend:add-menu:vie } %> - <a <%= AUIUtil.buildData(menuItem.getAnchorData()) %> class="btn btn-action btn-bottom-right btn-primary" data-placement="left" data-qa-id="addButton" data-toggle="tooltip" href="<%= HtmlUtil.escapeAttribute(menuItem.getUrl()) %>" id="<%= namespace + id %>" title="<%= title %>"> + <a <%= AUIUtil.buildData(menuItem.getAnchorData()) %> class="btn btn-action btn-bottom-right btn-primary" data-placement="left" data-qa-id="addButton" data-toggle="tooltip" href="<%= HtmlUtil.escapeAttribute(menuItem.getUrl()) %>" id="<%= namespace + id %>" title="<%= HtmlUtil.escapeAttribute(title) %>"> <aui:icon image="plus" markupView="lexicon" /> </a>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/add_button.jsp+1 −1 modified@@ -77,7 +77,7 @@ else { <portlet:param name="kbTemplateId" value="<%= String.valueOf(kbTemplate.getKbTemplateId()) %>" /> </liferay-portlet:renderURL> - <liferay-frontend:add-menu-item title="<%= LanguageUtil.get(resourceBundle, HtmlUtil.escape(kbTemplate.getTitle())) %>" url="<%= addKBArticleURL.toString() %>" /> + <liferay-frontend:add-menu-item title="<%= LanguageUtil.get(resourceBundle, kbTemplate.getTitle()) %>" url="<%= addKBArticleURL.toString() %>" /> <% }
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/article_asset_entries.jsp+2 −2 modified@@ -60,7 +60,7 @@ KBArticle kbArticle = (KBArticle)request.getAttribute(KBWebKeys.KNOWLEDGE_BASE_K <liferay-ui:icon iconCssClass="<%= assetRenderer.getIconCssClass() %>" label="<%= true %>" - message="<%= assetRenderer.getTitle(locale) %>" + message="<%= HtmlUtil.escape(assetRenderer.getTitle(locale)) %>" url="<%= KBArticleAssetEntriesUtil.getURL(request, themeDisplay, assetRendererFactory, assetRenderer) %>" /> @@ -92,7 +92,7 @@ KBArticle kbArticle = (KBArticle)request.getAttribute(KBWebKeys.KNOWLEDGE_BASE_K <liferay-ui:icon iconCssClass="<%= assetRenderer.getIconCssClass() %>" label="<%= true %>" - message="<%= assetRenderer.getTitle(locale) %>" + message="<%= HtmlUtil.escape(assetRenderer.getTitle(locale)) %>" url="<%= KBArticleAssetEntriesUtil.getURL(request, themeDisplay, assetRendererFactory, assetRenderer) %>" />
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/article_history.jsp+1 −1 modified@@ -117,7 +117,7 @@ <portlet:param name="resourcePrimKey" value="<%= String.valueOf(kbArticle.getResourcePrimKey()) %>" /> </portlet:renderURL> - var uri = '<%= compareVersionURL %>'; + var uri = '<%= HtmlUtil.escapeJS(compareVersionURL) %>'; uri = Liferay.Util.addParams('<portlet:namespace />sourceVersion=' + event.sourceversion, uri); uri = Liferay.Util.addParams('<portlet:namespace />targetVersion=' + event.targetversion, uri);
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/article_suggestions.jsp+1 −2 modified@@ -165,15 +165,14 @@ if (ratingsType == null) { <liferay-ui:search-container-row className="com.liferay.knowledge.base.model.KBComment" - escapedModel="<%= true %>" modelVar="kbComment" > <liferay-ui:search-container-column-text cssClass="kb-column-no-wrap" name="comment" orderable="<%= true %>" > - <%= kbComment.getContent() %> + <%= HtmlUtil.escape(kbComment.getContent()) %> </liferay-ui:search-container-column-text> <liferay-ui:search-container-column-date
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/article_tools.jsp+2 −2 modified@@ -24,9 +24,9 @@ int status = (Integer)request.getAttribute(KBWebKeys.KNOWLEDGE_BASE_STATUS); <div class="kb-article-tools"> <c:if test="<%= kbGroupServiceConfiguration.sourceURLEnabled() && Validator.isUrl(kbArticle.getSourceURL()) %>"> - <a href="<%= kbArticle.getSourceURL() %>" target="_blank"> + <a href="<%= HtmlUtil.escapeAttribute(kbArticle.getSourceURL()) %>" target="_blank"> <span class="kb-article-source-url label label-success"> - <liferay-ui:message key="<%= kbGroupServiceConfiguration.sourceURLEditMessageKey() %>" /> + <liferay-ui:message key="<%= HtmlUtil.escape(kbGroupServiceConfiguration.sourceURLEditMessageKey()) %>" /> </span> </a> </c:if>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/attachments.jsp+1 −1 modified@@ -64,7 +64,7 @@ if (kbArticle != null) { data="<%= data %>" iconCssClass="icon-paper-clip" label="<%= true %>" - message='<%= fileEntry.getTitle() + " (" + TextFormatter.formatStorageSize(fileEntry.getSize(), locale) + ")" %>' + message='<%= HtmlUtil.escape(fileEntry.getTitle()) + " (" + TextFormatter.formatStorageSize(fileEntry.getSize(), locale) + ")" %>' method="get" url="<%= rowURL %>" />
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/edit_article.jsp+1 −1 modified@@ -221,7 +221,7 @@ if (portletTitleBasedNavigation) { for (Map.Entry<String, String> entry : sectionsMap.entrySet()) { %> - <aui:option label="<%= entry.getKey() %>" selected="<%= ArrayUtil.contains(sections, entry.getValue()) %>" value="<%= entry.getValue() %>" /> + <aui:option label="<%= HtmlUtil.escape(entry.getKey()) %>" selected="<%= ArrayUtil.contains(sections, entry.getValue()) %>" value="<%= HtmlUtil.escape(entry.getValue()) %>" /> <% }
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/history.jsp+1 −1 modified@@ -197,7 +197,7 @@ if (portletTitleBasedNavigation) { <portlet:param name="resourcePrimKey" value="<%= String.valueOf(kbArticle.getResourcePrimKey()) %>" /> </portlet:renderURL> - var uri = '<%= compareVersionURL %>'; + var uri = '<%= HtmlUtil.escapeJS(compareVersionURL) %>'; uri = Liferay.Util.addParams('<portlet:namespace />sourceVersion=' + rowIds.eq(1).val(), uri); uri = Liferay.Util.addParams('<portlet:namespace />targetVersion=' + rowIds.eq(0).val(), uri);
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/move_object.jsp+1 −1 modified@@ -136,7 +136,7 @@ if (portletTitleBasedNavigation) { <portlet:param name="targetStatus" value="<%= String.valueOf(targetStatus) %>" /> </liferay-portlet:renderURL> - uri: '<%= selectKBObjectURL %>' + uri: '<%= HtmlUtil.escapeJS(selectKBObjectURL) %>' }, function(event) { document.<portlet:namespace />fm.<portlet:namespace />parentPriority.value = event.priority;
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/select_parent.jsp+4 −8 modified@@ -120,8 +120,6 @@ else { <% KBFolder kbFolder = (KBFolder)kbObject; - - kbFolder = kbFolder.toEscapedModel(); %> <liferay-portlet:renderURL var="rowURL" windowState="<%= LiferayWindowState.POP_UP.toString() %>"> @@ -148,11 +146,11 @@ else { <c:choose> <c:when test="<%= Validator.isNotNull(rowURL) %>"> <aui:a href="<%= rowURL %>"> - <%= kbFolder.getName() %> + <%= HtmlUtil.escape(kbFolder.getName()) %> </aui:a> </c:when> <c:otherwise> - <%= kbFolder.getName() %> + <%= HtmlUtil.escape(kbFolder.getName()) %> </c:otherwise> </c:choose> </liferay-ui:search-container-column-text> @@ -194,8 +192,6 @@ else { <% KBArticle kbArticle = (KBArticle)kbObject; - - kbArticle = kbArticle.toEscapedModel(); %> <liferay-portlet:renderURL var="rowURL" windowState="<%= LiferayWindowState.POP_UP.toString() %>"> @@ -223,11 +219,11 @@ else { <c:choose> <c:when test="<%= Validator.isNotNull(rowURL) %>"> <aui:a href="<%= rowURL %>"> - <%= kbArticle.getTitle() %> + <%= HtmlUtil.escape(kbArticle.getTitle()) %> </aui:a> </c:when> <c:otherwise> - <%= kbArticle.getTitle() %> + <%= HtmlUtil.escape(kbArticle.getTitle()) %> </c:otherwise> </c:choose> </liferay-ui:search-container-column-text>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/view_suggestion.jsp+1 −1 modified@@ -47,7 +47,7 @@ renderResponse.setTitle(kbCommentTitle); %> <h5 class="text-default"> - <liferay-ui:message arguments="<%= new String[] {kbComment.getUserName(), modifiedDateDescription} %>" key="x-suggested-x-ago" /> + <liferay-ui:message arguments="<%= new String[] {HtmlUtil.escape(kbComment.getUserName()), modifiedDateDescription} %>" key="x-suggested-x-ago" /> </h5> <h4>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/view_suggestions_by_status.jsp+1 −1 modified@@ -53,7 +53,7 @@ KBCommentResultRowSplitter resultRowSplitter = (KBCommentResultRowSplitter)reque %> <h5 class="text-default"> - <liferay-ui:message arguments="<%= new String[] {kbComment.getUserName(), modifiedDateDescription} %>" key="x-suggested-x-ago" /> + <liferay-ui:message arguments="<%= new String[] {HtmlUtil.escape(kbComment.getUserName()), modifiedDateDescription} %>" key="x-suggested-x-ago" /> </h5> <h4>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/import.jsp+2 −2 modified@@ -44,7 +44,7 @@ renderResponse.setTitle(LanguageUtil.get(resourceBundle, "import")); KBArticleImportException kbaie = (KBArticleImportException)errorException; %> - <%= LanguageUtil.format(request, "an-unexpected-error-occurred-while-importing-articles-x", kbaie.getLocalizedMessage()) %> + <%= LanguageUtil.format(request, "an-unexpected-error-occurred-while-importing-articles-x", HtmlUtil.escape(kbaie.getLocalizedMessage())) %> </liferay-ui:error> <liferay-ui:error exception="<%= UploadRequestSizeException.class %>"> @@ -56,7 +56,7 @@ renderResponse.setTitle(LanguageUtil.get(resourceBundle, "import")); <aui:field-wrapper> <div class="alert alert-info"> <liferay-ui:message - arguments="<%= StringUtil.merge(kbGroupServiceConfiguration.markdownImporterArticleExtensions(), StringPool.COMMA_AND_SPACE) %>" + arguments="<%= HtmlUtil.escape(StringUtil.merge(kbGroupServiceConfiguration.markdownImporterArticleExtensions(), StringPool.COMMA_AND_SPACE)) %>" key="upload-your-zip-file-help" /> </div>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/template_comment.jsp+1 −1 modified@@ -49,7 +49,7 @@ KBComment kbComment = (KBComment)request.getAttribute("template_comment.jsp-kb_c <br /> <div> - <%= kbComment.getContent() %> + <%= HtmlUtil.escape(kbComment.getContent()) %> </div> <br />
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/view.jsp+5 −9 modified@@ -183,7 +183,7 @@ if (parentResourcePrimKey != KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) { <c:otherwise> <div class="alert alert-warning"> <liferay-ui:message - arguments="<%= StringUtil.merge(kbGroupServiceConfiguration.markdownImporterArticleExtensions(), StringPool.COMMA_AND_SPACE) %>" + arguments="<%= HtmlUtil.escape(StringUtil.merge(kbGroupServiceConfiguration.markdownImporterArticleExtensions(), StringPool.COMMA_AND_SPACE)) %>" key="nothing-was-imported-no-articles-were-found-with-one-of-the-supported-extensions-x" /> </div> @@ -205,8 +205,6 @@ if (parentResourcePrimKey != KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) { <% KBFolder kbFolder = (KBFolder)kbObject; - kbFolder = kbFolder.toEscapedModel(); - Date modifiedDate = kbFolder.getModifiedDate(); String modifiedDateDescription = LanguageUtil.getTimeDescription(request, System.currentTimeMillis() - modifiedDate.getTime(), true); @@ -228,12 +226,12 @@ if (parentResourcePrimKey != KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) { <liferay-ui:search-container-column-text colspan="<%= 2 %>"> <h5 class="text-default"> - <liferay-ui:message arguments="<%= new String[] {kbFolder.getUserName(), modifiedDateDescription} %>" key="x-modified-x-ago" /> + <liferay-ui:message arguments="<%= new String[] {HtmlUtil.escape(kbFolder.getUserName()), modifiedDateDescription} %>" key="x-modified-x-ago" /> </h5> <h4> <aui:a href="<%= rowURL.toString() %>"> - <%= kbFolder.getName() %> + <%= HtmlUtil.escape(kbFolder.getName()) %> </aui:a> </h4> @@ -256,8 +254,6 @@ if (parentResourcePrimKey != KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) { <% KBArticle kbArticle = (KBArticle)kbObject; - kbArticle = kbArticle.toEscapedModel(); - Date modifiedDate = kbArticle.getModifiedDate(); String modifiedDateDescription = LanguageUtil.getTimeDescription(request, System.currentTimeMillis() - modifiedDate.getTime(), true); @@ -277,12 +273,12 @@ if (parentResourcePrimKey != KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) { <liferay-ui:search-container-column-text colspan="<%= 2 %>"> <h5 class="text-default"> - <liferay-ui:message arguments="<%= new String[] {kbArticle.getUserName(), modifiedDateDescription} %>" key="x-modified-x-ago" /> + <liferay-ui:message arguments="<%= new String[] {HtmlUtil.escape(kbArticle.getUserName()), modifiedDateDescription} %>" key="x-modified-x-ago" /> </h5> <h4> <aui:a href="<%= viewURL.toString() %>"> - <%= kbArticle.getTitle() %> + <%= HtmlUtil.escape(kbArticle.getTitle()) %> </aui:a> </h4>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/view_templates.jsp+2 −3 modified@@ -133,7 +133,6 @@ String keywords = ParamUtil.getString(request, "keywords"); <liferay-ui:search-container-row className="com.liferay.knowledge.base.model.KBTemplate" - escapedModel="<%= true %>" keyProperty="kbTemplateId" modelVar="kbTemplate" > @@ -152,7 +151,7 @@ String keywords = ParamUtil.getString(request, "keywords"); %> <h5 class="text-default"> - <liferay-ui:message arguments="<%= new String[] {kbTemplate.getUserName(), modifiedDateDescription} %>" key="x-modified-x-ago" /> + <liferay-ui:message arguments="<%= new String[] {HtmlUtil.escape(kbTemplate.getUserName()), modifiedDateDescription} %>" key="x-modified-x-ago" /> </h5> <liferay-portlet:renderURL var="editURL"> @@ -163,7 +162,7 @@ String keywords = ParamUtil.getString(request, "keywords"); <h4> <aui:a href="<%= editURL.toString() %>"> - <%= kbTemplate.getTitle() %> + <%= HtmlUtil.escape(kbTemplate.getTitle()) %> </aui:a> </h4> </liferay-ui:search-container-column-text>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/article/configuration.jsp+3 −3 modified@@ -42,10 +42,10 @@ kbArticlePortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBArtic <div class="form-group kb-field-wrapper"> <% - KBArticle kbArticle = KBArticleLocalServiceUtil.fetchLatestKBArticle(kbArticlePortletInstanceConfiguration.resourcePrimKey(), WorkflowConstants.STATUS_APPROVED); + KBArticle kbArticle = KBArticleServiceUtil.fetchLatestKBArticle(kbArticlePortletInstanceConfiguration.resourcePrimKey(), WorkflowConstants.STATUS_APPROVED); %> - <aui:input label="article" name="configurationKBArticle" type="resource" value="<%= (kbArticle != null) ? HtmlUtil.escape(kbArticle.getTitle()) : StringPool.BLANK %>" /> + <aui:input label="article" name="configurationKBArticle" type="resource" value="<%= (kbArticle != null) ? kbArticle.getTitle() : StringPool.BLANK %>" /> <aui:button name="selectKBArticleButton" value="select" /> </div> @@ -120,7 +120,7 @@ kbArticlePortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBArtic <portlet:param name="selectableClassNameIds" value="<%= String.valueOf(PortalUtil.getClassNameId(KBArticleConstants.getClassName())) %>" /> </liferay-portlet:renderURL> - uri: '<%= selectKBObjectURL %>' + uri: '<%= HtmlUtil.escapeJS(selectKBObjectURL) %>' }, function(event) { var kbArticleData = {
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/article/view_article.jsp+1 −1 modified@@ -20,7 +20,7 @@ <c:if test="<%= Objects.equals(portletDisplay.getId(), KBPortletKeys.KNOWLEDGE_BASE_ARTICLE_DEFAULT_INSTANCE) && PortletPermissionUtil.contains(permissionChecker, plid, portletDisplay.getId(), KBActionKeys.CONFIGURATION) %>"> <div class="alert alert-info portlet-configuration"> - <aui:a href="<%= portletDisplay.getURLConfiguration() %>" label='<%= LanguageUtil.format(request, "portlet-configuration-page-x-instance-id-x", new String[] {layout.getName(locale), portletDisplay.getInstanceId()}, false) %>' onClick="<%= portletDisplay.getURLConfigurationJS() %>" /> + <aui:a href="<%= portletDisplay.getURLConfiguration() %>" label='<%= LanguageUtil.format(request, "portlet-configuration-page-x-instance-id-x", new String[] {HtmlUtil.escape(layout.getName(locale)), portletDisplay.getInstanceId()}, false) %>' onClick="<%= portletDisplay.getURLConfigurationJS() %>" /> </div> </c:if>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/display/configuration.jsp+3 −3 modified@@ -56,7 +56,7 @@ kbDisplayPortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBDispl String title = StringPool.BLANK; if (resourceClassNameId != kbFolderClassNameId) { - KBArticle kbArticle = KBArticleLocalServiceUtil.fetchLatestKBArticle(kbDisplayPortletInstanceConfiguration.resourcePrimKey(), WorkflowConstants.STATUS_APPROVED); + KBArticle kbArticle = KBArticleServiceUtil.fetchLatestKBArticle(kbDisplayPortletInstanceConfiguration.resourcePrimKey(), WorkflowConstants.STATUS_APPROVED); if (kbArticle != null) { title = kbArticle.getTitle(); @@ -66,7 +66,7 @@ kbDisplayPortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBDispl title = LanguageUtil.get(resourceBundle, "home"); } else { - KBFolder kbFolder = KBFolderLocalServiceUtil.fetchKBFolder(kbDisplayPortletInstanceConfiguration.resourcePrimKey()); + KBFolder kbFolder = KBFolderServiceUtil.fetchKBFolder(kbDisplayPortletInstanceConfiguration.resourcePrimKey()); if (kbFolder != null) { title = kbFolder.getName(); @@ -153,7 +153,7 @@ kbDisplayPortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBDispl <portlet:param name="eventName" value='<%= liferayPortletResponse.getNamespace() + "selectKBObject" %>' /> </liferay-portlet:renderURL> - uri: '<%= selectKBObjectURL %>' + uri: '<%= HtmlUtil.escapeJS(selectKBObjectURL) %>' }, function(event) { document.<portlet:namespace />fm.<portlet:namespace />resourceClassNameId.value = event.resourceclassnameid;
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/display/content_root_selector.jsp+1 −1 modified@@ -45,7 +45,7 @@ List<KBFolder> kbFolders = KBUtil.getAlternateRootKBFolders(scopeGroupId, kbDisp selected="<%= currentKBFolderURLTitle.equals(kbFolder.getUrlTitle()) %>" value="<%= kbFolder.getKbFolderId() %>" > - <%= kbDisplayPortletInstanceConfiguration.contentRootPrefix() + " " + kbFolder.getName() %> + <%= HtmlUtil.escape(kbDisplayPortletInstanceConfiguration.contentRootPrefix() + " " + kbFolder.getName()) %> </aui:option> <%
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/display/view_article.jsp+1 −1 modified@@ -25,7 +25,7 @@ String[] searchKeywords = (String[])renderRequest.getAttribute(KBWebKeys.KNOWLED <c:if test="<%= Objects.equals(portletDisplay.getId(), KBPortletKeys.KNOWLEDGE_BASE_ARTICLE_DEFAULT_INSTANCE) && PortletPermissionUtil.contains(permissionChecker, plid, portletDisplay.getId(), KBActionKeys.CONFIGURATION) %>"> <div class="alert alert-info portlet-configuration"> - <aui:a href="<%= portletDisplay.getURLConfiguration() %>" label='<%= LanguageUtil.format(request, "portlet-configuration-page-x-instance-id-x", new String[] {layout.getName(locale), portletDisplay.getInstanceId()}, false) %>' onClick="<%= portletDisplay.getURLConfigurationJS() %>" /> + <aui:a href="<%= portletDisplay.getURLConfiguration() %>" label='<%= LanguageUtil.format(request, "portlet-configuration-page-x-instance-id-x", new String[] {HtmlUtil.escape(layout.getName(locale)), portletDisplay.getInstanceId()}, false) %>' onClick="<%= portletDisplay.getURLConfigurationJS() %>" /> </div> </c:if>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/init.jsp+1 −1 modified@@ -208,7 +208,7 @@ page import="javax.portlet.WindowState" %> <portlet:defineObjects /> <% -String redirect = ParamUtil.getString(request, "redirect", currentURL); +String redirect = PortalUtil.escapeRedirect(ParamUtil.getString(request, "redirect", currentURL)); String rootPortletId = portletDisplay.getRootPortletId();
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/search/view_prp_articles.jsp+6 −10 modified@@ -129,31 +129,27 @@ String orderByType = ParamUtil.getString(request, "orderByType", "desc"); <% AssetCategory assetCategory = AssetCategoryLocalServiceUtil.getAssetCategory(assetCategoryId); - assetCategory = assetCategory.toEscapedModel(); - AssetVocabulary assetVocabulary = AssetVocabularyLocalServiceUtil.getAssetVocabulary(assetCategory.getVocabularyId()); - - assetVocabulary = assetVocabulary.toEscapedModel(); %> <c:choose> <c:when test="<%= Validator.isNotNull(assetTagName) %>"> <c:choose> <c:when test="<%= total > 0 %>"> - <%= LanguageUtil.format(request, "articles-with-x-x-and-tag-x", new String[] {assetVocabulary.getTitle(locale), assetCategory.getTitle(locale), assetTagName}, false) %> + <%= LanguageUtil.format(request, "articles-with-x-x-and-tag-x", new String[] {HtmlUtil.escape(assetVocabulary.getTitle(locale)), HtmlUtil.escape(assetCategory.getTitle(locale)), HtmlUtil.escape(assetTagName)}, false) %> </c:when> <c:otherwise> - <%= LanguageUtil.format(request, "there-are-no-articles-with-x-x-and-tag-x", new String[] {assetVocabulary.getTitle(locale), assetCategory.getTitle(locale), assetTagName}, false) %> + <%= LanguageUtil.format(request, "there-are-no-articles-with-x-x-and-tag-x", new String[] {HtmlUtil.escape(assetVocabulary.getTitle(locale)), HtmlUtil.escape(assetCategory.getTitle(locale)), HtmlUtil.escape(assetTagName)}, false) %> </c:otherwise> </c:choose> </c:when> <c:otherwise> <c:choose> <c:when test="<%= total > 0 %>"> - <%= LanguageUtil.format(request, "articles-with-x-x", new String[] {assetVocabulary.getTitle(locale), assetCategory.getTitle(locale)}, false) %> + <%= LanguageUtil.format(request, "articles-with-x-x", new String[] {HtmlUtil.escape(assetVocabulary.getTitle(locale)), HtmlUtil.escape(assetCategory.getTitle(locale))}, false) %> </c:when> <c:otherwise> - <%= LanguageUtil.format(request, "there-are-no-articles-with-x-x", new String[] {assetVocabulary.getTitle(locale), assetCategory.getTitle(locale)}, false) %> + <%= LanguageUtil.format(request, "there-are-no-articles-with-x-x", new String[] {HtmlUtil.escape(assetVocabulary.getTitle(locale)), HtmlUtil.escape(assetCategory.getTitle(locale))}, false) %> </c:otherwise> </c:choose> </c:otherwise> @@ -162,10 +158,10 @@ String orderByType = ParamUtil.getString(request, "orderByType", "desc"); <c:otherwise> <c:choose> <c:when test="<%= total > 0 %>"> - <%= LanguageUtil.format(request, "articles-with-tag-x", assetTagName, false) %> + <%= LanguageUtil.format(request, "articles-with-tag-x", HtmlUtil.escape(assetTagName), false) %> </c:when> <c:otherwise> - <%= LanguageUtil.format(request, "there-are-no-articles-with-tag-x", assetTagName, false) %> + <%= LanguageUtil.format(request, "there-are-no-articles-with-tag-x", HtmlUtil.escape(assetTagName), false) %> </c:otherwise> </c:choose> </c:otherwise>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/section/configuration.jsp+1 −1 modified@@ -51,7 +51,7 @@ kbSectionPortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBSecti for (Map.Entry<String, String> entry : sectionsMap.entrySet()) { %> - <aui:option label="<%= entry.getKey() %>" selected="<%= ArrayUtil.contains(kbSectionPortletInstanceConfiguration.kbArticlesSections(), entry.getValue()) %>" value="<%= entry.getValue() %>" /> + <aui:option label="<%= HtmlUtil.escape(entry.getKey()) %>" selected="<%= ArrayUtil.contains(kbSectionPortletInstanceConfiguration.kbArticlesSections(), entry.getValue()) %>" value="<%= HtmlUtil.escape(entry.getValue()) %>" /> <% }
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/section/view.jsp+2 −2 modified@@ -50,7 +50,7 @@ String kbArticleDisplayStyle = kbSectionPortletInstanceConfiguration.kbArticleDi %> <div class="kb-articles-sections-title"> - <%= StringUtil.merge(titles, StringPool.COMMA_AND_SPACE) %> + <%= HtmlUtil.escape(StringUtil.merge(titles, StringPool.COMMA_AND_SPACE)) %> </div> </c:if> @@ -84,7 +84,7 @@ String kbArticleDisplayStyle = kbSectionPortletInstanceConfiguration.kbArticleDi <div class="kb-article-content"> <c:choose> <c:when test='<%= kbArticleDisplayStyle.equals("abstract") && Validator.isNotNull(kbArticle.getDescription()) %>'> - <%= kbArticle.getDescription() %> + <%= HtmlUtil.escape(kbArticle.getDescription()) %> </c:when> <c:when test='<%= kbArticleDisplayStyle.equals("abstract") %>'> <%= StringUtil.shorten(HtmlUtil.extractText(kbArticle.getContent()), 500) %>
util-taglib/src/com/liferay/taglib/ui/HeaderTag.java+3 −1 modified@@ -15,6 +15,7 @@ package com.liferay.taglib.ui; import com.liferay.portal.kernel.util.ParamUtil; +import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.taglib.util.IncludeTag; @@ -78,7 +79,8 @@ protected boolean isCleanUpSetAttributes() { protected void setAttributes(HttpServletRequest request) { request.setAttribute("liferay-ui:header:backLabel", _backLabel); - String redirect = ParamUtil.getString(request, "redirect"); + String redirect = PortalUtil.escapeRedirect( + ParamUtil.getString(request, "redirect")); if (Validator.isNull(_backURL) && Validator.isNotNull(redirect)) { request.setAttribute("liferay-ui:header:backURL", redirect);
ef2ba080f539LPS-72090 Escape more
2 files changed · +2 −2
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/article/configuration.jsp+1 −1 modified@@ -45,7 +45,7 @@ kbArticlePortletInstanceConfiguration = ParameterMapUtil.setParameterMap(KBArtic KBArticle kbArticle = KBArticleLocalServiceUtil.fetchLatestKBArticle(kbArticlePortletInstanceConfiguration.resourcePrimKey(), WorkflowConstants.STATUS_APPROVED); %> - <aui:input label="article" name="configurationKBArticle" type="resource" value="<%= (kbArticle != null) ? kbArticle.getTitle() : StringPool.BLANK %>" /> + <aui:input label="article" name="configurationKBArticle" type="resource" value="<%= (kbArticle != null) ? HtmlUtil.escape(kbArticle.getTitle()) : StringPool.BLANK %>" /> <aui:button name="selectKBArticleButton" value="select" /> </div>
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/section/view.jsp+1 −1 modified@@ -74,7 +74,7 @@ String kbArticleDisplayStyle = kbSectionPortletInstanceConfiguration.kbArticleDi <liferay-ui:icon iconCssClass="icon-file-alt" label="<%= true %>" - message="<%= kbArticle.getTitle() %>" + message="<%= HtmlUtil.escape(kbArticle.getTitle()) %>" method="get" url="<%= viewKBArticleURL.toString() %>" />
12c56b7f0684LPS-72090 XSS in KB article's and template's title when printing
2 files changed · +2 −2
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/print_article.jsp+1 −1 modified@@ -22,7 +22,7 @@ KBArticle kbArticle = (KBArticle)request.getAttribute(KBWebKeys.KNOWLEDGE_BASE_K <div class="float-container kb-entity-header"> <div class="kb-title"> - <%= kbArticle.getTitle() %> + <%= HtmlUtil.escape(kbArticle.getTitle()) %> </div> <div class="kb-tools">
modules/apps/knowledge-base/knowledge-base-web/src/main/resources/META-INF/resources/admin/common/print_template.jsp+1 −1 modified@@ -22,7 +22,7 @@ KBTemplate kbTemplate = (KBTemplate)request.getAttribute(KBWebKeys.KNOWLEDGE_BAS <div class="float-container kb-entity-header"> <div class="kb-title"> - <%= kbTemplate.getTitle() %> + <%= HtmlUtil.escape(kbTemplate.getTitle()) %> </div> <div class="kb-tools">
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- dev.liferay.com/web/community-security-team/known-vulnerabilities/liferay-portal-70/-/asset_publisher/cjE0ourZXJZE/content/cst-7017-multiple-xss-vulnerabilitiesnvdIssue TrackingPatchVendor Advisory
- github.com/brianchandotcom/liferay-portal/pull/48901nvdIssue TrackingPatchThird Party AdvisoryWEB
- github.com/advisories/GHSA-75x7-w445-5gwrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-12647ghsaADVISORY
- github.com/liferay/liferay-portal/commit/12c56b7f068416f02de56e29342b078d5d12b2b8ghsaWEB
- github.com/liferay/liferay-portal/commit/36b21590d1cac644864b10fbec02c2cac20098b3ghsaWEB
- github.com/liferay/liferay-portal/commit/461278bda30e7ec9e30270d0bbd70129383f7721ghsaWEB
- github.com/liferay/liferay-portal/commit/ef2ba080f53924d2437c021280f5ba70ba88c51dghsaWEB
- web.archive.org/web/20201101000000*/https://dev.liferay.com/web/community-security-team/known-vulnerabilities/liferay-portal-70/-/asset_publisher/cjE0ourZXJZE/content/cst-7017-multiple-xss-vulnerabilitiesghsaWEB
News mentions
0No linked articles in our index yet.