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

lukaszlenart pushed a commit to branch feature/WW-5504-request-nonce-s7
in repository https://gitbox.apache.org/repos/asf/struts.git

commit bca2c9b12c9b38f1f468926c282cf066f21f1c76
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Sun Jan 5 14:28:07 2025 +0100

    WW-5504 Allows to use request instead of session attribute to store nonce
---
 .../java/org/apache/struts2/StrutsConstants.java   |   7 ++
 .../java/org/apache/struts2/components/UIBean.java |  17 +++-
 .../config/StrutsBeanSelectionProvider.java        |   3 +
 .../StrutsDefaultConfigurationProvider.java        |   6 +-
 .../struts2/interceptor/csp/CspNonceReader.java    |  84 +++++++++++++++++
 .../struts2/interceptor/csp/CspNonceSource.java    |  27 ++++++
 .../interceptor/csp/DefaultCspSettings.java        | 101 +++++++++++++++------
 .../interceptor/csp/StrutsCspNonceReader.java      |  86 ++++++++++++++++++
 .../org/apache/struts2/default.properties          |   3 +
 core/src/main/resources/struts-beans.xml           |   3 +
 .../org/apache/struts2/components/UIBeanTest.java  |  36 ++++++++
 .../struts2/interceptor/CspInterceptorTest.java    |   2 +-
 .../struts2/views/java/simple/ActionErrorTest.java |   3 +
 .../views/java/simple/ActionMessageTest.java       |   3 +
 .../struts2/views/java/simple/AnchorTest.java      |   3 +
 .../struts2/views/java/simple/CheckboxTest.java    |   3 +
 .../views/java/simple/DateTextFieldTest.java       |   3 +
 .../struts2/views/java/simple/FieldErrorTest.java  |   3 +
 .../apache/struts2/views/java/simple/FileTest.java |   3 +
 .../apache/struts2/views/java/simple/FormTest.java |   3 +
 .../apache/struts2/views/java/simple/HeadTest.java |   3 +
 .../struts2/views/java/simple/HiddenTest.java      |   3 +
 .../struts2/views/java/simple/LabelTest.java       |   3 +
 .../apache/struts2/views/java/simple/LinkTest.java |   3 +
 .../struts2/views/java/simple/PasswordTest.java    |  14 +--
 .../struts2/views/java/simple/ResetTest.java       |   3 +
 .../struts2/views/java/simple/ScriptTest.java      |   3 +
 .../struts2/views/java/simple/SelectTest.java      |   3 +
 .../struts2/views/java/simple/SubmitTest.java      |   3 +
 .../struts2/views/java/simple/TextAreaTest.java    |   3 +
 .../struts2/views/java/simple/TextFieldTest.java   |   3 +
 .../struts2/views/java/simple/TokenTest.java       |   3 +
 32 files changed, 400 insertions(+), 46 deletions(-)

diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java 
b/core/src/main/java/org/apache/struts2/StrutsConstants.java
index ae722ae4d..3436f7773 100644
--- a/core/src/main/java/org/apache/struts2/StrutsConstants.java
+++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java
@@ -673,4 +673,11 @@ public final class StrutsConstants {
      * See {@link org.apache.struts2.interceptor.exec.ExecutorProvider}
      */
     public static final String STRUTS_EXECUTOR_PROVIDER = 
"struts.executor.provider";
+
+    /**
+     * See {@link org.apache.struts2.interceptor.csp.CspNonceReader}
+     * @since 6.8.0
+     */
+    public static final String STRUTS_CSP_NONCE_READER = 
"struts.csp.nonce.reader";
+    public static final String STRUTS_CSP_NONCE_SOURCE = 
"struts.csp.nonce.source";
 }
diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java 
b/core/src/main/java/org/apache/struts2/components/UIBean.java
index 0d5429099..adac94dba 100644
--- a/core/src/main/java/org/apache/struts2/components/UIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/UIBean.java
@@ -36,6 +36,7 @@ import 
org.apache.struts2.components.template.TemplateEngineManager;
 import org.apache.struts2.components.template.TemplateRenderingContext;
 import org.apache.struts2.dispatcher.AttributeMap;
 import org.apache.struts2.dispatcher.StaticContentLoader;
+import org.apache.struts2.interceptor.csp.CspNonceReader;
 import org.apache.struts2.util.ComponentUtils;
 import org.apache.struts2.util.TextProviderHelper;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
@@ -528,6 +529,8 @@ public abstract class UIBean extends Component {
 
     protected TemplateEngineManager templateEngineManager;
 
+    protected CspNonceReader cspNonceReader;
+
     @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
     public void setDefaultTemplateDir(String dir) {
         this.defaultTemplateDir = dir;
@@ -553,6 +556,11 @@ public abstract class UIBean extends Component {
         this.templateEngineManager = mgr;
     }
 
+    @Inject
+    public void setCspNonceReader(CspNonceReader cspNonceReader) {
+        this.cspNonceReader = cspNonceReader;
+    }
+
     @Override
     public boolean end(Writer writer, String body) {
         evaluateParams();
@@ -886,13 +894,12 @@ public abstract class UIBean extends Component {
         }
 
         // to be used with the CSP interceptor - adds the nonce value as a 
parameter to be accessed from ftl files
-        HttpSession session = 
stack.getActionContext().getServletRequest().getSession(false);
-        Object nonceValue = session != null ? session.getAttribute("nonce") : 
null;
+        CspNonceReader.NonceValue nonceValue = 
cspNonceReader.readNonceValue(stack);
 
-        if (nonceValue != null) {
-            addParameter("nonce", nonceValue.toString());
+        if (nonceValue.isNonceValueSet()) {
+            addParameter("nonce", nonceValue.getNonceValue());
         } else {
-            LOG.debug("Session is not active, cannot obtain nonce value");
+            LOG.debug("Nonce not defined in: {}", nonceValue.getSource());
         }
 
         evaluateExtraParams();
diff --git 
a/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java 
b/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java
index ace7b6875..6f73371d4 100644
--- 
a/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java
+++ 
b/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java
@@ -55,6 +55,7 @@ import org.apache.struts2.factory.UnknownHandlerFactory;
 import org.apache.struts2.factory.ValidatorFactory;
 import org.apache.struts2.inject.ContainerBuilder;
 import org.apache.struts2.inject.Scope;
+import org.apache.struts2.interceptor.csp.CspNonceReader;
 import org.apache.struts2.interceptor.exec.ExecutorProvider;
 import org.apache.struts2.ognl.BeanInfoCacheFactory;
 import org.apache.struts2.ognl.ExpressionCacheFactory;
@@ -450,6 +451,8 @@ public class StrutsBeanSelectionProvider extends 
AbstractBeanSelectionProvider {
 
         alias(ExecutorProvider.class, 
StrutsConstants.STRUTS_EXECUTOR_PROVIDER, builder, props, Scope.SINGLETON);
 
+        alias(CspNonceReader.class, StrutsConstants.STRUTS_CSP_NONCE_READER, 
builder, props, Scope.SINGLETON);
+
         switchDevMode(props);
     }
 
diff --git 
a/core/src/main/java/org/apache/struts2/config/providers/StrutsDefaultConfigurationProvider.java
 
b/core/src/main/java/org/apache/struts2/config/providers/StrutsDefaultConfigurationProvider.java
index 31bce4ec3..40d757586 100644
--- 
a/core/src/main/java/org/apache/struts2/config/providers/StrutsDefaultConfigurationProvider.java
+++ 
b/core/src/main/java/org/apache/struts2/config/providers/StrutsDefaultConfigurationProvider.java
@@ -68,6 +68,8 @@ import org.apache.struts2.validator.ValidatorFileParser;
 import ognl.PropertyAccessor;
 import org.apache.struts2.dispatcher.HttpParameters;
 import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.interceptor.csp.CspNonceReader;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 import org.apache.struts2.interceptor.exec.ExecutorProvider;
 import org.apache.struts2.interceptor.exec.StrutsExecutorProvider;
 import org.apache.struts2.url.QueryStringBuilder;
@@ -159,7 +161,9 @@ public class StrutsDefaultConfigurationProvider implements 
ConfigurationProvider
                 .factory(UrlEncoder.class, StrutsUrlEncoder.class, 
Scope.SINGLETON)
                 .factory(UrlDecoder.class, StrutsUrlDecoder.class, 
Scope.SINGLETON)
 
-                .factory(ExecutorProvider.class, StrutsExecutorProvider.class, 
Scope.SINGLETON);
+                .factory(ExecutorProvider.class, StrutsExecutorProvider.class, 
Scope.SINGLETON)
+
+                .factory(CspNonceReader.class, StrutsCspNonceReader.class, 
Scope.SINGLETON);
 
         for (Map.Entry<String, Object> entry : 
DefaultConfiguration.BOOTSTRAP_CONSTANTS.entrySet()) {
             props.setProperty(entry.getKey(), 
String.valueOf(entry.getValue()));
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceReader.java 
b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceReader.java
new file mode 100644
index 000000000..2e53d41a8
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceReader.java
@@ -0,0 +1,84 @@
+/*
+ * 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.struts2.interceptor.csp;
+
+import org.apache.struts2.util.ValueStack;
+
+/**
+ * Reads the nonce value using the ValueStack, {@link StrutsCspNonceReader} is 
the default implementation
+ * @since 6.8.0
+ */
+public interface CspNonceReader {
+
+    NonceValue readNonceValue(ValueStack stack);
+
+    class NonceValue {
+        private final String nonceValue;
+        private final CspNonceSource source;
+
+        private NonceValue(String nonceValue, CspNonceSource source) {
+            this.nonceValue = nonceValue;
+            this.source = source;
+        }
+
+        public static NonceValue ofSession(String nonceValue) {
+            return new NonceValue(nonceValue, CspNonceSource.SESSION);
+        }
+
+        public static NonceValue ofRequest(String nonceValue) {
+            return new NonceValue(nonceValue, CspNonceSource.REQUEST);
+        }
+
+        public static NonceValue ofNullSession() {
+            return new NonceValue(null, CspNonceSource.SESSION);
+        }
+
+        public static NonceValue ofNullRequest() {
+            return new NonceValue(null, CspNonceSource.REQUEST);
+        }
+
+        public boolean isNonceValueSet() {
+            return nonceValue != null;
+        }
+
+        public String getNonceValue() {
+            return nonceValue;
+        }
+
+        public CspNonceSource getSource() {
+            return source;
+        }
+
+        @Override
+        public String toString() {
+            String displayNonce;
+            if (nonceValue != null && nonceValue.length() >= 4) {
+                displayNonce = String.format("nonceValue='%s**********'", 
nonceValue.substring(0, 4));
+            } else if (nonceValue != null) {
+                displayNonce = String.format("nonceValue='%s**********'", 
nonceValue);
+            } else {
+                displayNonce = "nonceValue='<null>'";
+            }
+            return "NonceValue{" +
+                    displayNonce +
+                    ", source=" + source +
+                    '}';
+        }
+    }
+}
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceSource.java 
b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceSource.java
new file mode 100644
index 000000000..cc34e3581
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceSource.java
@@ -0,0 +1,27 @@
+/*
+ * 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.struts2.interceptor.csp;
+
+/**
+ * Source of the nonce value
+ */
+public enum CspNonceSource {
+    REQUEST,
+    SESSION
+}
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java 
b/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java
index 399ef4a4c..75ea7f17d 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java
@@ -20,13 +20,15 @@ package org.apache.struts2.interceptor.csp;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import org.apache.struts2.inject.Inject;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.action.CspSettingsAware;
 
 import java.security.SecureRandom;
 import java.util.Base64;
-import java.util.Objects;
 
 import static java.lang.String.format;
 
@@ -43,63 +45,102 @@ import static java.lang.String.format;
  */
 public class DefaultCspSettings implements CspSettings {
 
-    private final static Logger LOG = 
LogManager.getLogger(DefaultCspSettings.class);
+    private static final Logger LOG = 
LogManager.getLogger(DefaultCspSettings.class);
+    private static final String NONCE_KEY = "nonce";
 
     private final SecureRandom sRand = new SecureRandom();
 
+    private CspNonceSource nonceSource = CspNonceSource.SESSION;
+
     protected String reportUri;
     protected String reportTo;
     // default to reporting mode
     protected String cspHeader = CSP_REPORT_HEADER;
 
+    @Inject(value = StrutsConstants.STRUTS_CSP_NONCE_SOURCE, required = false)
+    public void setNonceSource(String nonceSource) {
+        if (StringUtils.isBlank(nonceSource)) {
+            this.nonceSource = CspNonceSource.SESSION;
+        } else {
+            this.nonceSource = 
CspNonceSource.valueOf(nonceSource.toUpperCase());
+        }
+    }
+
     @Override
     public void addCspHeaders(HttpServletRequest request, HttpServletResponse 
response) {
+        if (this.nonceSource == CspNonceSource.SESSION) {
+            addCspHeadersWithSession(request, response);
+        } else if (this.nonceSource == CspNonceSource.REQUEST) {
+            addCspHeadersWithRequest(request, response);
+        } else {
+            LOG.warn("Unknown nonce source: {}, ignoring CSP settings", 
nonceSource);
+        }
+    }
+
+    private void addCspHeadersWithSession(HttpServletRequest request, 
HttpServletResponse response) {
         if (isSessionActive(request)) {
             LOG.trace("Session is active, applying CSP settings");
-            associateNonceWithSession(request);
-            response.setHeader(cspHeader, createPolicyFormat(request));
+            String nonceValue = generateNonceValue();
+            request.getSession().setAttribute(NONCE_KEY, nonceValue);
+            response.setHeader(cspHeader, createPolicyFormat(nonceValue));
         } else {
-            LOG.trace("Session is not active, ignoring CSP settings");
+            LOG.debug("Session is not active, ignoring CSP settings");
         }
     }
 
+    private void addCspHeadersWithRequest(HttpServletRequest request, 
HttpServletResponse response) {
+        String nonceValue = generateNonceValue();
+        request.setAttribute(NONCE_KEY, nonceValue);
+        response.setHeader(cspHeader, createPolicyFormat(nonceValue));
+    }
+
     private boolean isSessionActive(HttpServletRequest request) {
         return request.getSession(false) != null;
     }
 
-    private void associateNonceWithSession(HttpServletRequest request) {
-        String nonceValue = 
Base64.getUrlEncoder().encodeToString(getRandomBytes());
-        request.getSession().setAttribute("nonce", nonceValue);
+    private String generateNonceValue() {
+        return Base64.getUrlEncoder().encodeToString(getRandomBytes());
     }
 
-    protected String createPolicyFormat(HttpServletRequest request) {
-        StringBuilder policyFormatBuilder = new StringBuilder()
-            .append(OBJECT_SRC)
-            .append(format(" '%s'; ", NONE))
-            .append(SCRIPT_SRC)
-            .append(" 'nonce-%s' ") // nonce placeholder
-            .append(format("'%s' ", STRICT_DYNAMIC))
-            .append(format("%s %s; ", HTTP, HTTPS))
-            .append(BASE_URI)
-            .append(format(" '%s'; ", NONE));
+    protected String createPolicyFormat(String nonceValue) {
+        StringBuilder builder = new StringBuilder()
+                .append(OBJECT_SRC)
+                .append(format(" '%s'; ", NONE))
+                .append(SCRIPT_SRC)
+                .append(format(" 'nonce-%s' ", nonceValue))
+                .append(format("'%s' ", STRICT_DYNAMIC))
+                .append(format("%s %s; ", HTTP, HTTPS))
+                .append(BASE_URI)
+                .append(format(" '%s'; ", NONE));
 
         if (reportUri != null) {
-            policyFormatBuilder
-                .append(REPORT_URI)
-                .append(format(" %s; ", reportUri));
-            if(reportTo != null) {
-                policyFormatBuilder
+            builder
+                    .append(REPORT_URI)
+                    .append(format(" %s; ", reportUri));
+            if (reportTo != null) {
+                builder
                         .append(REPORT_TO)
                         .append(format(" %s; ", reportTo));
             }
         }
 
-        return format(policyFormatBuilder.toString(), getNonceString(request));
+        return builder.toString();
+    }
+
+    /**
+     * @deprecated since 6.8.0, for removal
+     */
+    @Deprecated
+    protected String createPolicyFormat(HttpServletRequest request) {
+        throw new UnsupportedOperationException("Unsupported implementation, 
use createPolicyFormat(String) instead!");
     }
 
+    /**
+     * @deprecated since 6.8.0, for removal
+     */
+    @Deprecated
     protected String getNonceString(HttpServletRequest request) {
-        Object nonce = request.getSession().getAttribute("nonce");
-        return Objects.toString(nonce);
+        throw new UnsupportedOperationException("Unsupported implementation, 
don't use!");
     }
 
     private byte[] getRandomBytes() {
@@ -128,10 +169,10 @@ public class DefaultCspSettings implements CspSettings {
     @Override
     public String toString() {
         return "DefaultCspSettings{" +
-            "reportUri='" + reportUri + '\'' +
-            ", reportTo='" + reportTo + '\'' +
-            ", cspHeader='" + cspHeader + '\'' +
-            '}';
+                "reportUri='" + reportUri + '\'' +
+                ", reportTo='" + reportTo + '\'' +
+                ", cspHeader='" + cspHeader + '\'' +
+                '}';
     }
 
 }
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/StrutsCspNonceReader.java
 
b/core/src/main/java/org/apache/struts2/interceptor/csp/StrutsCspNonceReader.java
new file mode 100644
index 000000000..d857b8df9
--- /dev/null
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/csp/StrutsCspNonceReader.java
@@ -0,0 +1,86 @@
+/*
+ * 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.struts2.interceptor.csp;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpSession;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.inject.Inject;
+import org.apache.struts2.util.ValueStack;
+
+/**
+ * Reads nonce value from session or request attribute.
+ * @since 6.8.0
+ */
+public class StrutsCspNonceReader implements CspNonceReader {
+
+    private static final Logger LOG = 
LogManager.getLogger(StrutsCspNonceReader.class);
+
+    private final CspNonceSource nonceSource;
+
+    @Inject(value = StrutsConstants.STRUTS_CSP_NONCE_SOURCE, required = false)
+    public StrutsCspNonceReader(String source) {
+        if (StringUtils.isBlank(source)) {
+            this.nonceSource = CspNonceSource.SESSION;
+        } else {
+            this.nonceSource = CspNonceSource.valueOf(source.toUpperCase());
+        }
+    }
+
+    @Override
+    public NonceValue readNonceValue(ValueStack stack) {
+        HttpServletRequest request = 
stack.getActionContext().getServletRequest();
+        NonceValue nonceValue;
+
+        if (nonceSource == CspNonceSource.SESSION) {
+            LOG.debug("Reading nonce value from session");
+            nonceValue = readNonceFromSession(request);
+        } else if (nonceSource == CspNonceSource.REQUEST) {
+            LOG.debug("Reading nonce value from request attribute");
+            nonceValue = readNonceFromRequest(request);
+        } else {
+            LOG.warn("Unknown nonce source: {}, reading nonce value from 
session", nonceSource);
+            nonceValue = readNonceFromSession(request);
+        }
+        return nonceValue;
+    }
+
+    private NonceValue readNonceFromSession(HttpServletRequest request) {
+        HttpSession session = request.getSession(false);
+        Object nonceValue = session != null ? session.getAttribute("nonce") : 
null;
+        if (nonceValue == null) {
+            LOG.debug("Session is not active, cannot obtain nonce value");
+            return NonceValue.ofNullSession();
+        }
+        return NonceValue.ofSession(nonceValue.toString());
+    }
+
+    private NonceValue readNonceFromRequest(HttpServletRequest request) {
+        Object nonceValue = request.getAttribute("nonce");
+        if (nonceValue == null) {
+            LOG.warn("Request attribute 'nonce' is not set, cannot obtain 
nonce value");
+            return NonceValue.ofNullRequest();
+        }
+
+        return NonceValue.ofRequest(nonceValue.toString());
+    }
+}
diff --git a/core/src/main/resources/org/apache/struts2/default.properties 
b/core/src/main/resources/org/apache/struts2/default.properties
index ecda0efb6..175530e0e 100644
--- a/core/src/main/resources/org/apache/struts2/default.properties
+++ b/core/src/main/resources/org/apache/struts2/default.properties
@@ -299,4 +299,7 @@ struts.url.queryStringParser=strutsQueryStringParser
 struts.url.encoder=strutsUrlEncoder
 struts.url.decoder=strutsUrlDecoder
 
+### Defines source to read nonce value from, possible values are: request, 
session
+struts.csp.nonceSource=session
+
 ### END SNIPPET: complete_file
diff --git a/core/src/main/resources/struts-beans.xml 
b/core/src/main/resources/struts-beans.xml
index 3cbe12466..89f045b73 100644
--- a/core/src/main/resources/struts-beans.xml
+++ b/core/src/main/resources/struts-beans.xml
@@ -250,4 +250,7 @@
     <bean type="org.apache.struts2.interceptor.exec.ExecutorProvider" 
name="struts"
           class="org.apache.struts2.interceptor.exec.StrutsExecutorProvider"/>
 
+    <bean type="org.apache.struts2.interceptor.csp.CspNonceReader" 
name="struts"
+          class="org.apache.struts2.interceptor.csp.StrutsCspNonceReader"/>
+
 </struts>
diff --git a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java 
b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
index 874bf6d5d..cc194bd08 100644
--- a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
+++ b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
@@ -21,6 +21,7 @@ package org.apache.struts2.components;
 import org.apache.struts2.ActionContext;
 import org.apache.struts2.config.ConfigurationException;
 import org.apache.struts2.util.ValueStack;
+import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsInternalTestCase;
 import org.apache.struts2.components.template.Template;
 import org.apache.struts2.components.template.TemplateEngine;
@@ -32,6 +33,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockHttpSession;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import static 
org.apache.struts2.security.DefaultNotExcludedAcceptedPatternsCheckerTest.NO_EXCLUSION_ACCEPT_ALL_PATTERNS_CHECKER;
@@ -236,6 +238,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.setAccesskey(accesskeyValue);
         txtFld.evaluateParams();
 
@@ -250,6 +254,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.addParameter("value", value);
         txtFld.evaluateParams();
 
@@ -338,6 +344,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.setCssClass(cssClass);
         txtFld.evaluateParams();
 
@@ -352,6 +360,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.setStyle(cssStyle);
         txtFld.evaluateParams();
 
@@ -372,6 +382,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         actionContext.withSession(new SessionMap(req));
 
         DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
+        container.inject(dblSelect);
+
         dblSelect.evaluateParams();
 
         assertEquals(nonceVal, dblSelect.getAttributes().get("nonce"));
@@ -392,11 +404,35 @@ public class UIBeanTest extends StrutsInternalTestCase {
         session.invalidate();
 
         DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
+        container.inject(dblSelect);
+
         dblSelect.evaluateParams();
 
         assertNull(dblSelect.getAttributes().get("nonce"));
     }
 
+    public void testNonceOfRequestAttribute() {
+        Map<String, String> params = new HashMap<String, String>(){{
+            put(StrutsConstants.STRUTS_CSP_NONCE_SOURCE, "request");
+        }};
+        initDispatcher(params);
+
+        String nonceVal = "r4nd0m";
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        req.setAttribute("nonce", nonceVal);
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        ActionContext actionContext = stack.getActionContext();
+        actionContext.withServletRequest(req);
+
+        DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
+        container.inject(dblSelect);
+
+        dblSelect.evaluateParams();
+
+        assertEquals(nonceVal, dblSelect.getAttributes().get("nonce"));
+    }
+
     public void testSetNullUiStaticContentPath() {
         // given
         ValueStack stack = ActionContext.getContext().getValueStack();
diff --git 
a/core/src/test/java/org/apache/struts2/interceptor/CspInterceptorTest.java 
b/core/src/test/java/org/apache/struts2/interceptor/CspInterceptorTest.java
index 597c95394..3a9f83348 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/CspInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/CspInterceptorTest.java
@@ -312,7 +312,7 @@ public class CspInterceptorTest extends 
StrutsInternalTestCase {
     public static class CustomDefaultCspSettings extends DefaultCspSettings {
 
         @Override
-        protected String createPolicyFormat(HttpServletRequest request) {
+        protected String createPolicyFormat(String nonceValue) {
             return "foo";
         }
     }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
index 192e5a481..9129f24bc 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.components.ActionError;
 import org.apache.struts2.components.Anchor;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -72,6 +74,7 @@ public class ActionErrorTest extends AbstractTest {
         //errors are needed to setup stack
         super.setUp();
         this.tag = new ActionError(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
index bd550819f..8d8895372 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.ActionError;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -72,6 +74,7 @@ public class ActionMessageTest extends AbstractTest {
         //errors are needed to setup stack
         super.setUp();
         this.tag = new ActionError(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
index c3f7c96c6..d7512ccd3 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
@@ -24,6 +24,8 @@ import 
org.apache.struts2.security.DefaultNotExcludedAcceptedPatternsChecker;
 import org.apache.struts2.components.Anchor;
 import org.apache.struts2.components.UIBean;
 import org.apache.struts2.components.ServletUrlRenderer;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class AnchorTest extends AbstractTest {
     private Anchor tag;
@@ -111,6 +113,7 @@ public class AnchorTest extends AbstractTest {
         this.tag = new Anchor(stack, request, response);
         this.tag.setUrlRenderer(new ServletUrlRenderer());
         this.tag.setNotExcludedAcceptedPatterns(new 
DefaultNotExcludedAcceptedPatternsChecker());
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
index b6b49136f..b73c125d0 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.security.DefaultNotExcludedAcceptedPatternsChecker;
 import org.apache.struts2.components.Checkbox;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class CheckboxTest extends AbstractCommonAttributesTest {
     private Checkbox tag;
@@ -88,6 +90,7 @@ public class CheckboxTest extends 
AbstractCommonAttributesTest {
         super.setUp();
         tag = new Checkbox(stack, request, response);
         tag.setNotExcludedAcceptedPatterns(new 
DefaultNotExcludedAcceptedPatternsChecker());
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
index 67d9dc5a5..7b1d36069 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.DateTextField;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class DateTextFieldTest extends AbstractCommonAttributesTest {
 
@@ -56,6 +58,7 @@ public class DateTextFieldTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new DateTextField(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
index fe35a58a0..fca239293 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.FieldError;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.*;
 
@@ -100,6 +102,7 @@ public class FieldErrorTest extends AbstractTest {
         //errors are needed to setup stack
         super.setUp();
         this.tag = new FieldError(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
index bf9786f3a..dce590b30 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.File;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class FileTest extends AbstractCommonAttributesTest {
     private File tag;
@@ -50,6 +52,7 @@ public class FileTest extends AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new File(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
index 34d176962..9ee9c9152 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.components.Form;
 import org.apache.struts2.components.UIBean;
 import org.apache.struts2.components.UrlRenderer;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 import org.easymock.EasyMock;
 
 public class FormTest extends AbstractCommonAttributesTest {
@@ -80,5 +82,6 @@ public class FormTest extends AbstractCommonAttributesTest {
         UrlRenderer renderer = EasyMock.createNiceMock(UrlRenderer.class);
         EasyMock.replay(renderer);
         tag.setUrlRenderer(renderer);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
index a1c276280..ace29fdbc 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Head;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class HeadTest extends AbstractTest {
     private Head tag;
@@ -39,6 +41,7 @@ public class HeadTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Head(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
index 8884aaca0..c517a62e8 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Hidden;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class HiddenTest extends AbstractTest {
     private Hidden tag;
@@ -49,6 +51,7 @@ public class HiddenTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Hidden(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
index 0dfbb81ad..90cda064c 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Label;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class LabelTest extends AbstractCommonAttributesTest {
     private Label tag;
@@ -48,6 +50,7 @@ public class LabelTest extends AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Label(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
index 1fe7f0106..69c1a11bb 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
@@ -20,6 +20,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Link;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class LinkTest extends AbstractTest {
 
@@ -103,5 +105,6 @@ public class LinkTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Link(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
index a17e0fdce..ca12ff316 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
@@ -22,15 +22,14 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Password;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class PasswordTest extends AbstractCommonAttributesTest {
 
     private Password tag;
 
     public void testRenderPassword() throws Exception {
-        super.setUp();
-        this.tag = new Password(stack, request, response);
-
         tag.setName("name");
         tag.setValue("val1");
         tag.setSize("10");
@@ -51,9 +50,6 @@ public class PasswordTest extends 
AbstractCommonAttributesTest {
     }
 
     public void testRenderPasswordShowIt() throws Exception {
-        super.setUp();
-        this.tag = new Password(stack, request, response);
-
         tag.setName("name");
         tag.setValue("val1");
         tag.setSize("10");
@@ -75,7 +71,9 @@ public class PasswordTest extends 
AbstractCommonAttributesTest {
 
     @Override
     protected void setUp() throws Exception {
-        //dont call base setup
+        super.setUp();
+        this.tag = new Password(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
@@ -85,8 +83,6 @@ public class PasswordTest extends 
AbstractCommonAttributesTest {
 
     @Override
     protected UIBean getUIBean() throws Exception {
-        super.setUp();
-        this.tag = new Password(stack, request, response);
         return tag;
     }
 
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
index 9695e884f..14464145f 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Reset;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class ResetTest extends AbstractCommonAttributesTest {
     private Reset tag;
@@ -69,6 +71,7 @@ public class ResetTest extends AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Reset(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
index 8d5341aa2..ad042e964 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
@@ -21,6 +21,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.security.DefaultNotExcludedAcceptedPatternsChecker;
 import org.apache.struts2.components.Script;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 
 public class ScriptTest extends AbstractTest {
@@ -72,5 +74,6 @@ public class ScriptTest extends AbstractTest {
 
         this.tag = new Script(stack, request, response);
         tag.setNotExcludedAcceptedPatterns(new 
DefaultNotExcludedAcceptedPatternsChecker());
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
index 4fa2a6ed7..441d4e152 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Select;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -114,6 +116,7 @@ public class SelectTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Select(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
index 84f45c2d8..4760bcc5c 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Submit;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class SubmitTest extends AbstractCommonAttributesTest {
     private Submit tag;
@@ -154,6 +156,7 @@ public class SubmitTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Submit(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
index d72f42bcb..08d08caba 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.TextArea;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class TextAreaTest extends AbstractCommonAttributesTest {
     private TextArea tag;
@@ -71,6 +73,7 @@ public class TextAreaTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new TextArea(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
index 212a991cc..331442f13 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.TextField;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class TextFieldTest extends AbstractCommonAttributesTest {
     private TextField tag;
@@ -52,6 +54,7 @@ public class TextFieldTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new TextField(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
index 111ddcd50..4680e2bb1 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.ActionContext;
 import org.apache.struts2.components.Token;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.HashMap;
 import java.util.regex.Pattern;
@@ -49,6 +51,7 @@ public class TokenTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Token(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
 
         ActionContext.of()
             .withSession(new HashMap<>())

Reply via email to