This is an automated email from the ASF dual-hosted git repository.
ashishvijaywargiya pushed a commit to branch release24.09
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/release24.09 by this push:
new a3b1039944 Fixed: arbitrary service execution via Content.serviceName
in ContentWorker (#1791)
a3b1039944 is described below
commit a3b10399441d0d17c65c12a63c24d2ecf83ab306
Author: Ashish Vijaywargiya <[email protected]>
AuthorDate: Thu Aug 27 18:52:59 2026 +0530
Fixed: arbitrary service execution via Content.serviceName in ContentWorker
(#1791)
renderContentAsText resolved and ran whatever service name was stored in
Content.serviceName, a plain non-primary-key field writable by any
CONTENTMGR_CREATE/UPDATE account through createContent/updateContent,
using the live HTTP request parameters as the service's input. Some
content-rendering routes require no authentication, so an armed row
could be triggered anonymously.
- ContentWorker no longer reads Content.serviceName; the customMethodId
path now requires the referenced CustomMethod be typed CONTENT_RENDER
- Locked serviceName and customMethodId out of mass assignment on
createContent, updateContent, createProductContent and
updateProductContent
- Removed the now-dead serviceName field from the Catalog Manager
external content form
- Added CONTENT_RENDER as a seed CustomMethodType
Thank you Krishna Uprit for your help.
Cherry-picked from 555f76f7e3679d03f4813ba90edebf57a5fd27a3 (trunk,
#1788), excluding the accompanying ContentTests.groovy test changes.
---
applications/content/servicedef/services_content.xml | 8 ++++++++
.../org/apache/ofbiz/content/content/ContentWorker.java | 16 ++++++++++++++--
applications/product/servicedef/services.xml | 8 ++++++++
applications/product/widget/catalog/ProductForms.xml | 1 -
framework/common/data/CommonTypeData.xml | 3 +++
5 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/applications/content/servicedef/services_content.xml
b/applications/content/servicedef/services_content.xml
index 4adcb78963..5857a4476d 100644
--- a/applications/content/servicedef/services_content.xml
+++ b/applications/content/servicedef/services_content.xml
@@ -47,6 +47,10 @@
<override name="statusId" default-value="CTNT_IN_PROGRESS"/>
<override name="contentName" allow-html="safe"/>
<override name="description" allow-html="safe"/>
+ <!-- serviceName/customMethodId choose what code renderContentAsText
runs against the live request
+ parameters; neither is set through this generic mass-assignment
path (see ContentWorker.java) -->
+ <override name="serviceName" mode="OUT"/>
+ <override name="customMethodId" mode="OUT"/>
</service>
<service name="createTextAndUploadedContent" engine="groovy" auth="true"
@@ -140,6 +144,10 @@
<!-- end of deprecated fields -->
<override name="contentName" allow-html="safe"/>
<override name="description" allow-html="safe"/>
+ <!-- serviceName/customMethodId choose what code renderContentAsText
runs against the live request
+ parameters; neither is set through this generic mass-assignment
path (see ContentWorker.java) -->
+ <override name="serviceName" mode="OUT"/>
+ <override name="customMethodId" mode="OUT"/>
</service>
<service name="updateTextContent" engine="group" auth="true">
diff --git
a/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWorker.java
b/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWorker.java
index f7895cb53a..914f51ba61 100644
---
a/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWorker.java
+++
b/applications/content/src/main/java/org/apache/ofbiz/content/content/ContentWorker.java
@@ -197,10 +197,22 @@ public class ContentWorker implements
org.apache.ofbiz.widget.content.ContentWor
// if the content has a service attached run the service
Delegator delegator = dispatcher.getDelegator();
- String serviceName = content.getString("serviceName"); //Kept for
backward compatibility
+ // NOTE: Content.serviceName is a legacy, client-writable field
(createContent/updateContent both
+ // accept it as a plain non-PK attribute) that used to be resolved and
run here directly; that let
+ // anyone able to write a Content row choose an arbitrary service to
run with the live HTTP request
+ // parameters as its input. It is no longer honored. Only a
CustomMethod explicitly typed for
+ // content rendering may be run, so arming a row requires a
CustomMethod that was deliberately set
+ // up for this purpose, not just a string dropped into the Content row
itself.
+ String serviceName = null;
GenericValue custMethod = null;
if (UtilValidate.isNotEmpty(content.getString("customMethodId"))) {
- custMethod =
EntityQuery.use(delegator).from("CustomMethod").where("customMethodId",
content.get("customMethodId")).cache().queryOne();
+ custMethod = EntityQuery.use(delegator).from("CustomMethod")
+ .where("customMethodId", content.get("customMethodId"),
"customMethodTypeId", "CONTENT_RENDER")
+ .cache().queryOne();
+ if (custMethod == null) {
+ throw new GeneralException("customMethodId [" +
content.get("customMethodId")
+ + "] on content [" + content.get("contentId") + "] is
not a content rendering method");
+ }
}
if (custMethod != null) serviceName =
custMethod.getString("customMethodName");
if (UtilValidate.isNotEmpty(serviceName)) {
diff --git a/applications/product/servicedef/services.xml
b/applications/product/servicedef/services.xml
index ae6b975b52..fddd781c8e 100644
--- a/applications/product/servicedef/services.xml
+++ b/applications/product/servicedef/services.xml
@@ -366,6 +366,10 @@ under the License.
<auto-attributes include="nonpk" mode="IN" optional="true"/>
<auto-attributes entity-name="Content" include="nonpk" mode="IN"
optional="true"/>
<override name="fromDate" default-value="${date:nowTimestamp()}"/>
+ <!-- serviceName/customMethodId choose what code renderContentAsText
runs against the live request
+ parameters; neither is set through this generic mass-assignment
path (see ContentWorker.java) -->
+ <override name="serviceName" mode="OUT"/>
+ <override name="customMethodId" mode="OUT"/>
</service>
<service name="updateProductContent" default-entity-name="ProductContent"
engine="groovy"
location="component://product/src/main/groovy/org/apache/ofbiz/product/product/product/ProductContentServicesScript.groovy"
invoke="updateProductContent" auth="true">
@@ -373,6 +377,10 @@ under the License.
<auto-attributes include="pk" mode="IN" optional="false"/>
<auto-attributes include="nonpk" mode="IN" optional="true"/>
<auto-attributes entity-name="Content" include="nonpk" mode="IN"
optional="true"/>
+ <!-- serviceName/customMethodId choose what code renderContentAsText
runs against the live request
+ parameters; neither is set through this generic mass-assignment
path (see ContentWorker.java) -->
+ <override name="serviceName" mode="OUT"/>
+ <override name="customMethodId" mode="OUT"/>
</service>
<service name="removeProductContent" default-entity-name="ProductContent"
engine="entity-auto" invoke="delete" auth="true">
<description>Remove Content From Product</description>
diff --git a/applications/product/widget/catalog/ProductForms.xml
b/applications/product/widget/catalog/ProductForms.xml
index da80f0208b..839d95f0e8 100644
--- a/applications/product/widget/catalog/ProductForms.xml
+++ b/applications/product/widget/catalog/ProductForms.xml
@@ -775,7 +775,6 @@ under the License.
<field name="description"
title="${uiLabelMap.ProductProductDescription}" map-name="content"><text
size="40"/></field>
<field name="fromDate" title="${uiLabelMap.CommonFromDate}" ></field>
<field name="thruDate" title="${uiLabelMap.CommonThruDate}"></field>
- <field name="serviceName" title="${uiLabelMap.ProductServiceName}"
map-name="content"><text size="40"/></field>
<field use-when="contentId == null" name="contentId"
title="${uiLabelMap.ProductContentId}"
tooltip="${uiLabelMap.ProductOptional}"><text maxlength="20"/></field>
<field use-when="contentId != null" name="contentId"
title="${uiLabelMap.ProductContentId}"
tooltip="${uiLabelMap.ProductNotModificationRecrationProductContentAssociation}"
map-name="productContentData" ><display/></field>
<field name="productId"><hidden/></field>
diff --git a/framework/common/data/CommonTypeData.xml
b/framework/common/data/CommonTypeData.xml
index 70c32c91b3..53c675eed6 100644
--- a/framework/common/data/CommonTypeData.xml
+++ b/framework/common/data/CommonTypeData.xml
@@ -152,4 +152,7 @@ under the License.
<TelecomMethodType telecomMethodTypeId="SMS" description="Short Messaging
Service Method"/>
<TelecomMethodType telecomMethodTypeId="WHATSAPP" description="WhatsApp
Messaging Service Method"/>
<CustomMethodType customMethodTypeId="TELECOM_GATEWAY"
description="Telecom Gateway Custom Method"/>
+
+ <!-- Content Rendering Custom Method -->
+ <CustomMethodType customMethodTypeId="CONTENT_RENDER" description="Content
Rendering Method"/>
</entity-engine-xml>