This is an automated email from the ASF dual-hosted git repository.

nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 0fce1dd56c Improved: Improve ViewHandler interface (OFBIZ-13179) (#858)
0fce1dd56c is described below

commit 0fce1dd56c76e3dde0d27085ddd90d692560a8e2
Author: Nicolas Malin <nicolas.ma...@nereide.fr>
AuthorDate: Thu Nov 28 17:19:50 2024 +0100

    Improved: Improve ViewHandler interface (OFBIZ-13179) (#858)
    
    We extend *AbstractViewHandler* with a new method to override 
*prepareViewContext*.
    For each view handler implementation this will allow to control context 
used for rendering, applying Scriptlet token detection for security purpose.
    
    A new class *SecuredFreemarker* has been created to manage freemarker 
specific controls, outside global *SecurityUtil* class.
    
    We also add a new parameter *secure-context* (set true by default) to 
view-map xml element to indicate that this view allow unsecure rendering, this 
implies the view-map to required authentication.
    
    Thanks to Gil Portenseigne for help
---
 .../org/apache/ofbiz/content/cms/CmsEvents.java    |   2 +-
 .../content/view/SimpleContentViewHandler.java     |  37 ++++--
 .../ofbiz/product/category/SeoContextFilter.java   |   4 +-
 .../apache/ofbiz/security/SecuredFreemarker.java   | 131 +++++++++++++++++++++
 .../org/apache/ofbiz/security/SecurityUtil.java    |  72 -----------
 framework/webapp/dtd/site-conf.xsd                 |  10 ++
 .../ofbiz/webapp/control/ConfigXMLReader.java      |  13 +-
 .../apache/ofbiz/webapp/control/ControlFilter.java |   7 +-
 .../ofbiz/webapp/control/RequestHandler.java       |   3 +-
 .../ofbiz/webapp/ftl/FreeMarkerViewHandler.java    |  59 +++++-----
 .../apache/ofbiz/webapp/view/HttpViewHandler.java  |   9 +-
 .../apache/ofbiz/webapp/view/JspViewHandler.java   |  19 ++-
 .../org/apache/ofbiz/webapp/view/ViewHandler.java  |  14 ++-
 .../ofbiz/widget/renderer/ScreenRenderer.java      |  13 +-
 .../widget/renderer/fo/ScreenFopViewHandler.java   |  75 +++++++-----
 .../renderer/macro/MacroScreenViewHandler.java     |  15 ++-
 16 files changed, 314 insertions(+), 169 deletions(-)

diff --git 
a/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
 
b/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
index 173ecaaa91..2012f2d5cc 100644
--- 
a/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
+++ 
b/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
@@ -294,7 +294,7 @@ public final class CmsEvents {
                 if (statusCode == HttpServletResponse.SC_OK || hasErrorPage) {
                     // create the template map
                     MapStack<String> templateMap = MapStack.create();
-                    ScreenRenderer.populateContextForRequest(templateMap, 
null, request, response, servletContext);
+                    ScreenRenderer.populateContextForRequest(templateMap, 
null, request, response, servletContext, true);
                     templateMap.put("statusCode", statusCode);
 
                     // make the link prefix
diff --git 
a/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
 
b/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
index 8b697f0358..ae177cd102 100644
--- 
a/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
+++ 
b/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.sql.Timestamp;
 import java.text.ParseException;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -44,9 +45,11 @@ import org.apache.ofbiz.entity.Delegator;
 import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.entity.util.EntityQuery;
 import org.apache.ofbiz.entity.util.EntityUtilProperties;
+import org.apache.ofbiz.security.SecuredFreemarker;
 import org.apache.ofbiz.service.GenericServiceException;
 import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ServiceUtil;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 import org.apache.ofbiz.webapp.view.AbstractViewHandler;
 import org.apache.ofbiz.webapp.view.ViewHandlerException;
 import org.apache.ofbiz.webapp.website.WebSiteWorker;
@@ -62,24 +65,36 @@ public class SimpleContentViewHandler extends 
AbstractViewHandler {
         rootDir = context.getRealPath("/");
         https = (String) context.getAttribute("https");
     }
+
+    @Override
+    public Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+        List<String> fields = List.of("contentId", "rootContentId", "mapKey",
+                "contentAssocTypeId", "fromDate", "dataResourceId",
+                "contentRevisionSeqId", "mimeTypeId");
+        Map<String, Object> context = new HashMap<>();
+        fields.forEach(field -> context.put(field, 
request.getParameter(field)));
+        return viewMap.isSecureContext()
+                ? SecuredFreemarker.sanitizeParameterMap(context)
+                : context;
+    }
+
     /**
-     * @see org.apache.ofbiz.webapp.view.ViewHandler#render(java.lang.String, 
java.lang.String, java.lang.String, java.lang.String,
-     * java.lang.String, javax.servlet.http.HttpServletRequest, 
javax.servlet.http.HttpServletResponse)
+     * @see org.apache.ofbiz.webapp.view.ViewHandler#render(String, String, 
String, String, String, HttpServletRequest, HttpServletResponse, Map)
      */
     @Override
     public void render(String name, String page, String info, String 
contentType, String encoding, HttpServletRequest request,
-                       HttpServletResponse response) throws 
ViewHandlerException {
+                       HttpServletResponse response, Map<String, Object> 
context) throws ViewHandlerException {
         LocalDispatcher dispatcher = (LocalDispatcher) 
request.getAttribute("dispatcher");
         HttpSession session = request.getSession();
         GenericValue userLogin = (GenericValue) 
session.getAttribute("userLogin");
-        String contentId = request.getParameter("contentId");
-        String rootContentId = request.getParameter("rootContentId");
-        String mapKey = request.getParameter("mapKey");
-        String contentAssocTypeId = request.getParameter("contentAssocTypeId");
-        String fromDateStr = request.getParameter("fromDate");
-        String dataResourceId = request.getParameter("dataResourceId");
-        String contentRevisionSeqId = 
request.getParameter("contentRevisionSeqId");
-        String mimeTypeId = request.getParameter("mimeTypeId");
+        String contentId = (String) context.get("contentId");
+        String rootContentId = (String) context.get("rootContentId");
+        String mapKey = (String) context.get("mapKey");
+        String contentAssocTypeId = (String) context.get("contentAssocTypeId");
+        String fromDateStr = (String) context.get("fromDate");
+        String dataResourceId = (String) context.get("dataResourceId");
+        String contentRevisionSeqId = (String) 
context.get("contentRevisionSeqId");
+        String mimeTypeId = (String) context.get("mimeTypeId");
         Locale locale = UtilHttp.getLocale(request);
         String webSiteId = WebSiteWorker.getWebSiteId(request);
 
diff --git 
a/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
 
b/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
index bea4d8a7ae..0b7e638782 100644
--- 
a/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
+++ 
b/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
@@ -48,7 +48,7 @@ import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.StringUtil;
 import org.apache.ofbiz.base.util.UtilHttp;
 import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.security.SecurityUtil;
+import org.apache.ofbiz.security.SecuredFreemarker;
 import org.apache.ofbiz.webapp.SeoConfigUtil;
 import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 import org.apache.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig;
@@ -116,7 +116,7 @@ public final class SeoContextFilter implements Filter {
             uri = uri + "?" + queryString;
         }
 
-        if (SecurityUtil.containsFreemarkerInterpolation(httpRequest, 
httpResponse, uri)) {
+        if (SecuredFreemarker.containsFreemarkerInterpolation(httpRequest, 
httpResponse, uri)) {
             return;
         }
 
diff --git 
a/framework/security/src/main/java/org/apache/ofbiz/security/SecuredFreemarker.java
 
b/framework/security/src/main/java/org/apache/ofbiz/security/SecuredFreemarker.java
new file mode 100644
index 0000000000..b0b788d0ec
--- /dev/null
+++ 
b/framework/security/src/main/java/org/apache/ofbiz/security/SecuredFreemarker.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ 
*******************************************************************************/
+package org.apache.ofbiz.security;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.StringUtil;
+import org.apache.ofbiz.base.util.UtilHttp;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+
+public class SecuredFreemarker {
+    private static final String MODULE = SecuredFreemarker.class.getName();
+    private static final List<String> FTL_INTERPOLATION = List.of("%24%7B", 
"${", "%3C%23", "<#", "%23%7B", "#{", "%5B%3D", "[=", "%5B%23", "[#");
+
+    /*
+     * Prevents Freemarker exploits
+     * @param req
+     * @param resp
+     * @param uri
+     * @throws IOException
+     */
+    public static boolean containsFreemarkerInterpolation(HttpServletRequest 
req, HttpServletResponse resp, String uri)
+            throws IOException {
+        String urisOkForFreemarker = 
UtilProperties.getPropertyValue("security", 
"allowedURIsForFreemarkerInterpolation");
+        List<String> urisOK = UtilValidate.isNotEmpty(urisOkForFreemarker) ? 
StringUtil.split(urisOkForFreemarker, ",")
+                                                                           : 
new ArrayList<>();
+        String uriEnd = uri.substring(uri.lastIndexOf("/") + 1, uri.length());
+
+        if (!urisOK.contains(uriEnd)) {
+            Map<String, String[]> parameterMap = req.getParameterMap();
+            if (uri.contains("ecomseo")) { // SeoContextFilter call
+                if (containsFreemarkerInterpolation(resp, uri)) {
+                    return true;
+                }
+            } else if (!parameterMap.isEmpty()) { // ControlFilter call
+                List<BasicNameValuePair> params = new ArrayList<>();
+                parameterMap.forEach((name, values) -> {
+                    for (String value : values) {
+                        params.add(new BasicNameValuePair(name, value));
+                    }
+                });
+                String queryString = URLEncodedUtils.format(params, 
Charset.forName("UTF-8"));
+                uri = uri + "?" + queryString;
+                if (containsFreemarkerInterpolation(resp, uri)) {
+                    return true;
+                }
+            } else if (!UtilHttp.getAttributeMap(req).isEmpty()) { // Call 
with Content-Type modified by a MITM attack (rare case)
+                String attributeMap = UtilHttp.getAttributeMap(req).toString();
+                if (containsFreemarkerInterpolation(resp, attributeMap)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param resp
+     * @param stringToCheck
+     * @throws IOException
+     */
+    public static boolean containsFreemarkerInterpolation(HttpServletResponse 
resp, String stringToCheck) throws IOException {
+        if (containsFreemarkerInterpolation(stringToCheck)) { // not used OOTB 
in OFBiz, but possible
+            Debug.logError("===== Not saved for security reason, strings '${', 
'<#', '#{', '[=' or '[#' not accepted in fields! =====", MODULE);
+            resp.sendError(HttpServletResponse.SC_FORBIDDEN,
+                    "Not saved for security reason, strings '${', '<#', '#{', 
'[=' or '[#' not accepted in fields!");
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Analyze if stringToCheck contains a freemarker template
+     * @param stringToCheck
+     * @return true if freemarker template is detected
+     */
+    public static boolean containsFreemarkerInterpolation(String 
stringToCheck) {
+        return UtilValidate.isNotEmpty(stringToCheck)
+                && 
FTL_INTERPOLATION.stream().anyMatch(stringToCheck::contains);
+    }
+
+    /**
+     * Analyse each entry contains on params. If a freemarker template is 
detected, sanatize it to escape any exploit
+     * @param params
+     * @return Map with all values sanitized
+     */
+    public static Map<String, Object> sanitizeParameterMap(Map<String, Object> 
params) {
+        List<Map.Entry<String, Object>> unsafeEntries = 
params.entrySet().stream()
+                .filter(entry -> entry.getValue() instanceof String
+                        && containsFreemarkerInterpolation((String) 
entry.getValue()))
+                .toList();
+        if (!unsafeEntries.isEmpty()) {
+            Map<String, Object> paramsSanitize = new HashMap<>(params);
+            unsafeEntries.forEach(entry -> {
+                String sanitazedValue = (String) entry.getValue();
+                for (String interpolation : FTL_INTERPOLATION) {
+                    sanitazedValue = sanitazedValue.replace(interpolation, 
"##");
+                }
+                paramsSanitize.put(entry.getKey(), sanitazedValue);
+            });
+            return paramsSanitize;
+        }
+        return params;
+    }
+}
diff --git 
a/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java 
b/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
index 446a1a475c..7648ab49c6 100644
--- 
a/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
+++ 
b/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
@@ -19,23 +19,14 @@
 package org.apache.ofbiz.security;
 
 
-import java.io.IOException;
-import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.message.BasicNameValuePair;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.StringUtil;
-import org.apache.ofbiz.base.util.UtilHttp;
 import org.apache.ofbiz.base.util.UtilMisc;
-import org.apache.ofbiz.base.util.UtilProperties;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.entity.Delegator;
 import org.apache.ofbiz.entity.GenericEntityException;
@@ -172,67 +163,4 @@ public final class SecurityUtil {
         return false;
     }
 
-    /*
-     * Prevents Freemarker exploits
-     * @param req
-     * @param resp
-     * @param uri
-     * @throws IOException
-     */
-    public static boolean containsFreemarkerInterpolation(HttpServletRequest 
req, HttpServletResponse resp, String uri)
-            throws IOException {
-        String urisOkForFreemarker = 
UtilProperties.getPropertyValue("security", 
"allowedURIsForFreemarkerInterpolation");
-        List<String> urisOK = UtilValidate.isNotEmpty(urisOkForFreemarker) ? 
StringUtil.split(urisOkForFreemarker, ",")
-                                                                           : 
new ArrayList<>();
-        String uriEnd = uri.substring(uri.lastIndexOf("/") + 1, uri.length());
-
-        if (!urisOK.contains(uriEnd)) {
-            Map<String, String[]> parameterMap = req.getParameterMap();
-            if (uri.contains("ecomseo")) { // SeoContextFilter call
-                if (containsFreemarkerInterpolation(resp, uri)) {
-                    return true;
-                }
-            } else if (!parameterMap.isEmpty()) { // ControlFilter call
-                List<BasicNameValuePair> params = new ArrayList<>();
-                parameterMap.forEach((name, values) -> {
-                    for (String value : values) {
-                        params.add(new BasicNameValuePair(name, value));
-                    }
-                });
-                String queryString = URLEncodedUtils.format(params, 
Charset.forName("UTF-8"));
-                uri = uri + "?" + queryString;
-                if (SecurityUtil.containsFreemarkerInterpolation(resp, uri)) {
-                    return true;
-                }
-            } else if (!UtilHttp.getAttributeMap(req).isEmpty()) { // Call 
with Content-Type modified by a MITM attack (rare case)
-                String attributeMap = UtilHttp.getAttributeMap(req).toString();
-                if (containsFreemarkerInterpolation(resp, attributeMap)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @param resp
-     * @param stringToCheck
-     * @throws IOException
-     */
-    public static boolean containsFreemarkerInterpolation(HttpServletResponse 
resp, String stringToCheck) throws IOException {
-        if (stringToCheck.contains("%24%7B") || stringToCheck.contains("${")
-                || stringToCheck.contains("%3C%23") || 
stringToCheck.contains("<#")
-                || stringToCheck.contains("%23%7B") || 
stringToCheck.contains("#{")
-                || stringToCheck.contains("%5B%3D") || 
stringToCheck.contains("[=")
-                || stringToCheck.contains("%5B%23") || 
stringToCheck.contains("[#")) { // not used OOTB in OFBiz, but possible
-
-            Debug.logError("===== Not saved for security reason, strings '${', 
'<#', '#{', '[=' or '[#' not accepted in fields! =====",
-                    MODULE);
-            resp.sendError(HttpServletResponse.SC_FORBIDDEN,
-                    "Not saved for security reason, strings '${', '<#', '#{', 
'[=' or '[#' not accepted in fields!");
-            return true;
-        } else {
-            return false;
-        }
-    }
 }
diff --git a/framework/webapp/dtd/site-conf.xsd 
b/framework/webapp/dtd/site-conf.xsd
index cbf2cfde81..79a02b7986 100644
--- a/framework/webapp/dtd/site-conf.xsd
+++ b/framework/webapp/dtd/site-conf.xsd
@@ -792,6 +792,16 @@ under the License.
                 </xs:documentation>
             </xs:annotation>
         </xs:attribute>
+        <xs:attribute type="xs:boolean" name="secure-context" default="true">
+            <xs:annotation>
+                <xs:documentation>
+                    If secure-context=false, we authorize to forward to the 
renderer some parameters with interpretable code.
+                    This raise a potential risk of code injection. This can be 
usefully for some administration page to
+                    configure templating (like ftl for email or dynamic screen 
template).
+                    For this reason if secure-context=false, auth is set as 
true.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
         <xs:attribute name="x-frame-options" default="sameorigin">
             <xs:annotation>
                 <xs:documentation>
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
index 59c3b91756..d6a16d3856 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
@@ -1044,6 +1044,7 @@ public final class ConfigXMLReader {
         private String strictTransportSecurity;
         private String description;
         private boolean noCache = false;
+        private boolean secureContext = true;
         private boolean securityAuth = false;
 
         /**
@@ -1105,6 +1106,15 @@ public final class ConfigXMLReader {
             return noCache;
         }
 
+        /**
+         * Is secureContext boolean.
+         *
+         * @return the boolean
+         */
+        public boolean isSecureContext() {
+            return secureContext;
+        }
+
         /**
          * Gets type.
          * @return the type
@@ -1144,7 +1154,8 @@ public final class ConfigXMLReader {
             this.info = viewMapElement.getAttribute("info");
             this.contentType = viewMapElement.getAttribute("content-type");
             this.noCache = 
"true".equals(viewMapElement.getAttribute("no-cache"));
-            this.securityAuth = 
"true".equals(viewMapElement.getAttribute("auth"));
+            this.secureContext = 
"true".equals(viewMapElement.getAttribute("secure-context"));
+            this.securityAuth = 
"true".equals(viewMapElement.getAttribute("auth")) || !this.secureContext;
             this.encoding = viewMapElement.getAttribute("encoding");
             this.xFrameOption = viewMapElement.getAttribute("x-frame-options");
             this.strictTransportSecurity = 
viewMapElement.getAttribute("strict-transport-security");
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
index f2c2a5a37d..ca8d2cca69 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
@@ -41,11 +41,8 @@ import org.apache.logging.log4j.ThreadContext;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.entity.GenericValue;
+import org.apache.ofbiz.security.SecuredFreemarker;
 import org.apache.ofbiz.security.SecuredUpload;
-import org.apache.ofbiz.security.SecurityUtil;
-
-
-
 
 /**
  * A Filter used to specify an allowlist of allowed paths to the OFBiz 
application.
@@ -166,7 +163,7 @@ public class ControlFilter extends HttpFilter {
 
             GenericValue userLogin = (GenericValue) 
session.getAttribute("userLogin");
             if (!LoginWorker.hasBasePermission(userLogin, req)) { // Allows 
UEL and FlexibleString (OFBIZ-12602)
-                if (isSolrTest() && 
SecurityUtil.containsFreemarkerInterpolation(req, resp, uri)) {
+                if (isSolrTest() && 
SecuredFreemarker.containsFreemarkerInterpolation(req, resp, uri)) {
                     return;
                 }
             }
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
index f02efae40f..9ec279ad67 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
@@ -1285,7 +1285,8 @@ public final class RequestHandler {
                 Debug.logVerbose("Rendering view [" + nextPage + "] of type [" 
+ viewMap.getType() + "]", MODULE);
             }
             ViewHandler vh = viewFactory.getViewHandler(viewMap.getType());
-            vh.render(view, nextPage, viewMap.getInfo(), contentType, charset, 
req, resp);
+            Map<String, Object> context = vh.prepareViewContext(req, resp, 
viewMap);
+            vh.render(view, nextPage, viewMap.getInfo(), contentType, charset, 
req, resp, context);
         } catch (ViewHandlerException e) {
             Throwable throwable = e.getNested() != null ? e.getNested() : e;
             throw new RequestHandlerException(e.getNonNestedMessage(), 
throwable);
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
index aa1974f5ad..05df6ea933 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
@@ -30,6 +30,8 @@ import org.apache.ofbiz.base.util.UtilHttp;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.base.util.collections.MapStack;
 import org.apache.ofbiz.base.util.template.FreeMarkerWorker;
+import org.apache.ofbiz.security.SecuredFreemarker;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 import org.apache.ofbiz.webapp.view.AbstractViewHandler;
 import org.apache.ofbiz.webapp.view.ViewHandlerException;
 
@@ -53,36 +55,10 @@ public class FreeMarkerViewHandler extends 
AbstractViewHandler {
     }
 
     @Override
-    public void render(String name, String page, String info, String 
contentType, String encoding,
-            HttpServletRequest request, HttpServletResponse response) throws 
ViewHandlerException {
-        if (UtilValidate.isEmpty(page)) {
-            throw new ViewHandlerException("Invalid template source");
-        }
-
-        // make the root context (data model) for freemarker
-        MapStack<String> context = MapStack.create();
-        prepOfbizRoot(context, request, response);
-
-        // process the template & flush the output
-        try {
-            if (page.startsWith("component://")) {
-                FreeMarkerWorker.renderTemplate(page, context, 
response.getWriter());
-            } else {
-                // backwards compatibility
-                Template template = config.getTemplate(page);
-                FreeMarkerWorker.renderTemplate(template, context, 
response.getWriter());
-            }
-            response.flushBuffer();
-        } catch (TemplateException te) {
-            throw new ViewHandlerException("Problems processing Freemarker 
template", te);
-        } catch (IOException ie) {
-            throw new ViewHandlerException("Problems writing to output 
stream", ie);
-        }
-    }
-
-    public static void prepOfbizRoot(Map<String, Object> root, 
HttpServletRequest request, HttpServletResponse response) {
+    public Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
         ServletContext servletContext = request.getServletContext();
         HttpSession session = request.getSession();
+        MapStack<String> root = MapStack.create();
 
         // add in the OFBiz objects
         root.put("delegator", request.getAttribute("delegator"));
@@ -110,11 +86,38 @@ public class FreeMarkerViewHandler extends 
AbstractViewHandler {
 
         // add the request parameters -- this now uses a Map from UtilHttp
         Map<String, Object> requestParameters = 
UtilHttp.getParameterMap(request);
+        if (viewMap.isSecureContext()) {
+            requestParameters = 
SecuredFreemarker.sanitizeParameterMap(requestParameters);
+        }
         root.put("requestParameters", requestParameters);
 
         // add the TabLibFactory
         TaglibFactory jspTaglibs = new TaglibFactory(servletContext);
         root.put("JspTaglibs", jspTaglibs);
+        return root;
+    }
+
+    @Override
+    public void render(String name, String page, String info, String 
contentType, String encoding,
+                       HttpServletRequest request, HttpServletResponse 
response, Map<String, Object> context) throws ViewHandlerException {
+        if (UtilValidate.isEmpty(page)) {
+            throw new ViewHandlerException("Invalid template source");
+        }
 
+        // process the template & flush the output
+        try {
+            if (page.startsWith("component://")) {
+                FreeMarkerWorker.renderTemplate(page, context, 
response.getWriter());
+            } else {
+                // backwards compatibility
+                Template template = config.getTemplate(page);
+                FreeMarkerWorker.renderTemplate(template, context, 
response.getWriter());
+            }
+            response.flushBuffer();
+        } catch (TemplateException te) {
+            throw new ViewHandlerException("Problems processing Freemarker 
template", te);
+        } catch (IOException ie) {
+            throw new ViewHandlerException("Problems writing to output 
stream", ie);
+        }
     }
 }
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
index fc8ad691be..f46c4d58df 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
@@ -20,6 +20,7 @@ package org.apache.ofbiz.webapp.view;
 
 import java.io.IOException;
 
+import java.util.Map;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -28,6 +29,7 @@ import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.HttpClient;
 import org.apache.ofbiz.base.util.HttpClientException;
 import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 
 /**
  * ViewHandlerException - View Handler Exception
@@ -40,9 +42,14 @@ public class HttpViewHandler extends AbstractViewHandler {
     public void init(ServletContext context) throws ViewHandlerException {
     }
 
+    @Override
+    public Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+        return Map.of();
+    }
+
     @Override
     public void render(String name, String page, String info, String 
contentType, String encoding, HttpServletRequest request, HttpServletResponse
-            response) throws ViewHandlerException {
+            response, Map<String, Object> context) throws ViewHandlerException 
{
         // some containers call filters on EVERY request, even forwarded ones,
         // so let it know that it came from the control servlet
 
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
index 23c04aa0e4..3112f34dbd 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
@@ -20,6 +20,7 @@ package org.apache.ofbiz.webapp.view;
 
 import java.io.IOException;
 
+import java.util.Map;
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -29,6 +30,7 @@ import javax.servlet.jsp.JspException;
 
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 import org.apache.ofbiz.webapp.control.ControlFilter;
 
 /**
@@ -37,16 +39,21 @@ import org.apache.ofbiz.webapp.control.ControlFilter;
 public class JspViewHandler extends AbstractViewHandler {
 
     private static final String MODULE = JspViewHandler.class.getName();
-    private ServletContext context;
+    private ServletContext servletContext;
 
     @Override
-    public void init(ServletContext context) throws ViewHandlerException {
-        this.context = context;
+    public void init(ServletContext servletContext) throws 
ViewHandlerException {
+        this.servletContext = servletContext;
+    }
+
+    @Override
+    public Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+        return Map.of();
     }
 
     @Override
     public void render(String name, String page, String contentType, String 
encoding, String info, HttpServletRequest request, HttpServletResponse
-            response) throws ViewHandlerException {
+            response, Map<String, Object> context) throws ViewHandlerException 
{
         // some containers call filters on EVERY request, even forwarded ones,
         // so let it know that it came from the control servlet
 
@@ -66,10 +73,10 @@ public class JspViewHandler extends AbstractViewHandler {
 
         if (rd == null) {
             Debug.logInfo("HttpServletRequest.getRequestDispatcher() failed; 
trying ServletContext", MODULE);
-            rd = context.getRequestDispatcher(page);
+            rd = this.servletContext.getRequestDispatcher(page);
             if (rd == null) {
                 Debug.logInfo("ServletContext.getRequestDispatcher() failed; 
trying ServletContext.getNamedDispatcher(\"jsp\")", MODULE);
-                rd = context.getNamedDispatcher("jsp");
+                rd = this.servletContext.getNamedDispatcher("jsp");
                 if (rd == null) {
                     throw new ViewHandlerException("Source returned a null 
dispatcher (" + page + ")");
                 }
diff --git 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
index 6df8ec7b38..6c7591b096 100644
--- 
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
+++ 
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
@@ -18,9 +18,11 @@
  
*******************************************************************************/
 package org.apache.ofbiz.webapp.view;
 
+import java.util.Map;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 
 /**
  * ViewHandler - View Handler Interface
@@ -55,8 +57,18 @@ public interface ViewHandler {
      * @param info An info string attached to this view
      * @param request The HttpServletRequest object used when requesting this 
page.
      * @param response The HttpServletResponse object to be used to present 
the page.
+     * @param context  The context prepare by the handler to run
      * @throws ViewHandlerException
      */
     void render(String name, String page, String info, String contentType, 
String encoding, HttpServletRequest request,
-                HttpServletResponse response) throws ViewHandlerException;
+                HttpServletResponse response, Map<String, Object> context) 
throws ViewHandlerException;
+
+    /**
+     * Before call the render, this function have to purpose to analyse, 
secure and prepare the context
+     * @param request
+     * @param response
+     * @param viewMap
+     * @return
+     */
+    Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap);
 }
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
index 24174f7f24..26d3334545 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
@@ -49,6 +49,7 @@ import org.apache.ofbiz.entity.Delegator;
 import org.apache.ofbiz.entity.GenericEntity;
 import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.entity.util.EntityUtilProperties;
+import org.apache.ofbiz.security.SecuredFreemarker;
 import org.apache.ofbiz.security.Security;
 import org.apache.ofbiz.service.DispatchContext;
 import org.apache.ofbiz.service.GenericServiceException;
@@ -219,12 +220,13 @@ public class ScreenRenderer {
      * @param response
      * @param servletContext
      */
-    public void populateContextForRequest(HttpServletRequest request, 
HttpServletResponse response, ServletContext servletContext) {
-        populateContextForRequest(context, this, request, response, 
servletContext);
+    public void populateContextForRequest(HttpServletRequest request, 
HttpServletResponse response,
+                                          ServletContext servletContext, 
boolean secureParameters) {
+        populateContextForRequest(context, this, request, response, 
servletContext, secureParameters);
     }
 
     public static void populateContextForRequest(MapStack<String> context, 
ScreenRenderer screens, HttpServletRequest request,
-                                                 HttpServletResponse response, 
ServletContext servletContext) {
+                                                 HttpServletResponse response, 
ServletContext servletContext, boolean secureParameters) {
         HttpSession session = request.getSession();
 
         // attribute names to skip for session and application attributes; 
these are all handled as special cases,
@@ -232,6 +234,9 @@ public class ScreenRenderer {
         Set<String> attrNamesToSkip = UtilMisc.toSet("delegator", 
"dispatcher", "security", "webSiteId",
                 "org.apache.catalina.jsp_classpath");
         Map<String, Object> parameterMap = UtilHttp.getCombinedMap(request, 
attrNamesToSkip);
+        if (secureParameters) {
+            parameterMap = 
SecuredFreemarker.sanitizeParameterMap(parameterMap);
+        }
 
         GenericValue userLogin = (GenericValue) 
session.getAttribute("userLogin");
 
@@ -288,7 +293,7 @@ public class ScreenRenderer {
         context.put("requestAttributes", new HttpRequestHashModel(request, 
FreeMarkerWorker.getDefaultOfbizWrapper()));
         TaglibFactory jspTaglibs = new TaglibFactory(servletContext);
         context.put("JspTaglibs", jspTaglibs);
-        context.put("requestParameters", UtilHttp.getParameterMap(request));
+        context.put("requestParameters", 
SecuredFreemarker.sanitizeParameterMap(UtilHttp.getParameterMap(request)));
 
         ServletContextHashModel ftlServletContext = (ServletContextHashModel) 
request.getAttribute("ftlServletContext");
         context.put("Application", ftlServletContext);
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
index 8185738853..e2aac75248 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
@@ -25,6 +25,7 @@ import java.io.StringReader;
 import java.io.StringWriter;
 import java.io.Writer;
 
+import java.util.Map;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -39,8 +40,11 @@ import org.apache.fop.render.pdf.PDFEncryptionOption;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.GeneralException;
 import org.apache.ofbiz.base.util.UtilCodec;
+import org.apache.ofbiz.base.util.UtilGenerics;
 import org.apache.ofbiz.base.util.UtilHttp;
 import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.base.util.collections.MapStack;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 import org.apache.ofbiz.webapp.view.AbstractViewHandler;
 import org.apache.ofbiz.webapp.view.ApacheFopWorker;
 import org.apache.ofbiz.webapp.view.ViewHandlerException;
@@ -72,14 +76,21 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
         this.servletContext = context;
     }
 
+
+    @Override
+    public Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+        MapStack<String> context = MapStack.create();
+        ScreenRenderer.populateContextForRequest(context, null, request, 
response, servletContext, viewMap.isSecureContext());
+        return context;
+    }
+
     /**
-     * @see org.apache.ofbiz.webapp.view.ViewHandler#render(java.lang.String, 
java.lang.String, java.lang.String, java.lang.String, java.lang.String,
-     * javax.servlet.http.HttpServletRequest, 
javax.servlet.http.HttpServletResponse)
+     * @see org.apache.ofbiz.webapp.view.ViewHandler#render(String, String, 
String, String, String, HttpServletRequest, HttpServletResponse, Map)
      */
     @SuppressWarnings("unchecked")
     @Override
     public void render(String name, String page, String info, String 
contentType, String encoding, HttpServletRequest request,
-                       HttpServletResponse response) throws 
ViewHandlerException {
+                       HttpServletResponse response, Map<String, Object> 
context) throws ViewHandlerException {
         VisualTheme visualTheme = UtilHttp.getVisualTheme(request);
         ModelTheme modelTheme = visualTheme.getModelTheme();
 
@@ -92,15 +103,14 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
             // TODO: uncomment these lines when the renderers are implemented
             //TreeStringRenderer treeStringRenderer = new 
MacroTreeRenderer(modelTheme.getTreeRendererLocation(getName()), writer);
             //MenuStringRenderer menuStringRenderer = new 
MacroMenuRenderer(modelTheme.getMenuRendererLocation(getName()), writer);
-            ScreenRenderer screens = new ScreenRenderer(writer, null, 
screenStringRenderer);
-            screens.populateContextForRequest(request, response, 
servletContext);
+            ScreenRenderer screens = new ScreenRenderer(writer, 
UtilGenerics.cast(context), screenStringRenderer);
 
             // this is the object used to render forms from their definitions
             screens.getContext().put("formStringRenderer", formStringRenderer);
             screens.getContext().put("simpleEncoder", 
UtilCodec.getEncoder(modelTheme.getEncoder(getName())));
             screens.render(page);
         } catch (IOException | GeneralException | SAXException | 
ParserConfigurationException | TemplateException e) {
-            renderError("Problems with the response writer/output stream", e, 
"[Not Yet Rendered]", request, response);
+            renderError("Problems with the response writer/output stream", e, 
"[Not Yet Rendered]", request, response, context);
             return;
         }
 
@@ -118,21 +128,21 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
         }
         // get encryption related parameters
         FOUserAgent foUserAgent = null;
-        String userPassword = request.getParameter("userPassword");
-        String ownerPassword = request.getParameter("ownerPassword");
-        boolean allowPrint = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowPrint"))
-                ? ApacheFopWorker.getAllowPrintDefault() : 
request.getParameter("allowPrint"));
-        boolean allowCopyContent = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowCopyContent"))
-                ? ApacheFopWorker.getAllowCopyContentDefault() : 
request.getParameter("allowCopyContent"));
-        boolean allowEditContent = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowEditContent"))
-                ? ApacheFopWorker.getAllowEditContentDefault() : 
request.getParameter("allowEditContent"));
-        boolean allowEditAnnotations = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowEditAnnotations"))
-                ? ApacheFopWorker.getAllowEditAnnotationsDefault() : 
request.getParameter("allowEditAnnotations"));
+        String userPassword = (String) context.get("userPassword");
+        String ownerPassword = (String) context.get("ownerPassword");
+        boolean allowPrint = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowPrint"))
+                ? ApacheFopWorker.getAllowPrintDefault() : (String) 
context.get("allowPrint"));
+        boolean allowCopyContent = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowCopyContent"))
+                ? ApacheFopWorker.getAllowCopyContentDefault() : (String) 
context.get("allowCopyContent"));
+        boolean allowEditContent = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowEditContent"))
+                ? ApacheFopWorker.getAllowEditContentDefault() : (String) 
context.get("allowEditContent"));
+        boolean allowEditAnnotations = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowEditAnnotations"))
+                ? ApacheFopWorker.getAllowEditAnnotationsDefault() : (String) 
context.get("allowEditAnnotations"));
         if (UtilValidate.isNotEmpty(userPassword) || 
UtilValidate.isNotEmpty(ownerPassword) || !allowPrint || !allowCopyContent || 
allowEditContent
                 || !allowEditAnnotations) {
             int encryptionLength = 128;
             try {
-                encryptionLength = 
Integer.parseInt(request.getParameter("encryption-length"));
+                encryptionLength = Integer.parseInt((String) 
context.get("encryption-length"));
             } catch (NumberFormatException e) {
                 try {
                     encryptionLength = 
Integer.parseInt(ApacheFopWorker.getEncryptionLengthDefault());
@@ -141,16 +151,16 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
                 }
             }
 
-            boolean encryptMetadata = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("encrypt-metadata"))
-                    ? ApacheFopWorker.getEncryptMetadataDefault() : 
request.getParameter("encrypt-metadata"));
-            boolean allowFillInForms = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowFillInForms"))
-                    ? ApacheFopWorker.getAllowFillInFormsDefault() : 
request.getParameter("allowFillInForms"));
-            boolean allowAccessContent = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowAccessContent"))
-                    ? ApacheFopWorker.getAllowAccessContentDefault() : 
request.getParameter("allowAccessContent"));
-            boolean allowAssembleDocument = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowAssembleDocument"))
-                    ? ApacheFopWorker.getAllowAssembleDocumentDefault() : 
request.getParameter("allowAssembleDocument"));
-            boolean allowPrintHq = 
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowPrintHq"))
-                    ? ApacheFopWorker.getAllowPrintHqDefault() : 
request.getParameter("allowPrintHq"));
+            boolean encryptMetadata = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("encrypt-metadata"))
+                    ? ApacheFopWorker.getEncryptMetadataDefault() : (String) 
context.get("encrypt-metadata"));
+            boolean allowFillInForms = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowFillInForms"))
+                    ? ApacheFopWorker.getAllowFillInFormsDefault() : (String) 
context.get("allowFillInForms"));
+            boolean allowAccessContent = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowAccessContent"))
+                    ? ApacheFopWorker.getAllowAccessContentDefault() : 
(String) context.get("allowAccessContent"));
+            boolean allowAssembleDocument = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowAssembleDocument"))
+                    ? ApacheFopWorker.getAllowAssembleDocumentDefault() : 
(String) context.get("allowAssembleDocument"));
+            boolean allowPrintHq = 
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowPrintHq"))
+                    ? ApacheFopWorker.getAllowPrintHqDefault() : (String) 
context.get("allowPrintHq"));
             FopFactory fopFactory = ApacheFopWorker.getFactoryInstance();
             foUserAgent = fopFactory.newFOUserAgent();
             PDFEncryptionParams pdfEncryptionParams = new 
PDFEncryptionParams(userPassword, ownerPassword, allowPrint, allowCopyContent,
@@ -179,7 +189,7 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
             Fop fop = ApacheFopWorker.createFopInstance(out, contentType, 
foUserAgent);
             ApacheFopWorker.transform(src, null, fop);
         } catch (Exception e) {
-            renderError("Unable to transform FO file", e, screenOutString, 
request, response);
+            renderError("Unable to transform FO file", e, screenOutString, 
request, response, context);
             return;
         }
         // set the content type and length
@@ -191,7 +201,7 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
             out.writeTo(response.getOutputStream());
             response.getOutputStream().flush();
         } catch (IOException e) {
-            renderError("Unable to write to OutputStream", e, screenOutString, 
request, response);
+            renderError("Unable to write to OutputStream", e, screenOutString, 
request, response, context);
         }
     }
 
@@ -204,7 +214,9 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
      * @param response        the response
      * @throws ViewHandlerException the view handler exception
      */
-    protected void renderError(String msg, Exception e, String 
screenOutString, HttpServletRequest request, HttpServletResponse response)
+    protected void renderError(String msg, Exception e, String screenOutString,
+                               HttpServletRequest request, HttpServletResponse 
response,
+                               Map<String, Object> context)
             throws ViewHandlerException {
         Debug.logError(msg + ": " + e + "; Screen XSL:FO text was:\n" + 
screenOutString, MODULE);
         try {
@@ -214,8 +226,7 @@ public class ScreenFopViewHandler extends 
AbstractViewHandler {
             ScreenStringRenderer screenStringRenderer = new 
MacroScreenRenderer(modelTheme.getType("screen"),
                     modelTheme.getScreenRendererLocation("screen"));
 
-            ScreenRenderer screens = new ScreenRenderer(writer, null, 
screenStringRenderer);
-            screens.populateContextForRequest(request, response, 
servletContext);
+            ScreenRenderer screens = new ScreenRenderer(writer, 
UtilGenerics.cast(context), screenStringRenderer);
             screens.getContext().put("errorMessage", msg + ": " + e);
             screens.render(DEFAULT_ERROR_TEMPLATE);
             response.setContentType("text/html");
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
index 4365a7bbaf..19350f6938 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
@@ -33,6 +33,7 @@ import org.apache.ofbiz.base.util.UtilCodec;
 import org.apache.ofbiz.base.util.UtilHttp;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.base.util.collections.MapStack;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
 import org.apache.ofbiz.webapp.view.AbstractViewHandler;
 import org.apache.ofbiz.webapp.view.ViewHandlerException;
 import org.apache.ofbiz.widget.model.ModelTheme;
@@ -83,9 +84,17 @@ public class MacroScreenViewHandler extends 
AbstractViewHandler {
         return screenStringRenderer;
     }
 
+
+    @Override
+    public Map<String, Object> prepareViewContext(HttpServletRequest request, 
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+        MapStack<String> context = MapStack.create();
+        ScreenRenderer.populateContextForRequest(context, null, request, 
response, servletContext, viewMap.isSecureContext());
+        return context;
+    }
+
     @Override
     public void render(String name, String page, String info, String 
contentType, String encoding, HttpServletRequest request,
-                       HttpServletResponse response) throws 
ViewHandlerException {
+                       HttpServletResponse response, Map<String, Object> 
context) throws ViewHandlerException {
         try {
             Writer writer = response.getWriter();
             VisualTheme visualTheme = UtilHttp.getVisualTheme(request);
@@ -106,10 +115,8 @@ public class MacroScreenViewHandler extends 
AbstractViewHandler {
                 // to speed up output.
                 writer = new StandardCompress().getWriter(writer, null);
             }
-            MapStack<String> context = MapStack.create();
-            ScreenRenderer.populateContextForRequest(context, null, request, 
response, servletContext);
             ScreenStringRenderer screenStringRenderer = loadRenderers(request, 
response, context, writer);
-            ScreenRenderer screens = new ScreenRenderer(writer, context, 
screenStringRenderer);
+            ScreenRenderer screens = new ScreenRenderer(writer, 
MapStack.create(context), screenStringRenderer);
             context.put("screens", screens);
             context.put("simpleEncoder", 
UtilCodec.getEncoder(visualTheme.getModelTheme().getEncoder(getName())));
             screenStringRenderer.renderBegin(writer, context);

Reply via email to