[java-identity-provider] 01/08: IDP-2183 - Use of JS in views needs to be hardened via CSP
Scott Cantor
cantor.2 at osu.edu
Mon Nov 6 15:07:50 UTC 2023
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=c5c50d2446c56e86edabc281ce7a291432d180c0
commit c5c50d2446c56e86edabc281ce7a291432d180c0
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Oct 24 14:28:42 2023 -0400
IDP-2183 - Use of JS in views needs to be hardened via CSP
https://shibboleth.atlassian.net/browse/IDP-2183
Add beans to support hashing and nonce generation.
Initial CSP support to limit Javascript in views.
---
idp-authn-impl/pom.xml | 9 +++---
.../authn/spnego/impl/SPNEGOAuthnController.java | 33 +++++++++++++++++++++-
.../net/shibboleth/idp/conf/mvc-beans.xml | 4 ++-
.../net/shibboleth/idp/conf/primitives.xml | 25 ++++++++++++++++
.../net/shibboleth/idp/flows/admin/hello-flow.xml | 2 ++
.../shibboleth/idp/flows/admin/mdquery-flow.xml | 2 ++
.../idp/flows/admin/resolvertest-flow.xml | 2 ++
.../net/shibboleth/idp/flows/admin/status-flow.xml | 2 ++
.../idp/flows/admin/unlock-keys-flow.xml | 4 +++
.../idp/flows/authn/password-authn-flow.xml | 2 ++
.../shibboleth/idp/flows/cas/cas-abstract-flow.xml | 2 ++
.../client-storage/client-storage-read-flow.xml | 2 ++
.../client-storage/client-storage-write-flow.xml | 2 ++
.../idp/flows/intercept/attribute-release-flow.xml | 2 ++
.../idp/flows/intercept/expiring-password-flow.xml | 2 ++
.../idp/flows/intercept/impersonate-flow.xml | 2 ++
.../idp/flows/intercept/terms-of-use-flow.xml | 4 ++-
.../idp/flows/intercept/warning-flow.xml | 2 ++
.../shibboleth/idp/flows/logout/logout-flow.xml | 10 +++++++
.../idp/flows/logout/logout-propagation-flow.xml | 2 ++
.../idp/flows/saml/saml-abstract-flow.xml | 4 +++
.../idp/flows/saml/saml2/slo-back-flow.xml | 2 ++
.../flows/saml/saml2/slo-front-abstract-flow.xml | 10 +++++++
.../idp/module/flows/user/prefs/prefs-flow.xml | 2 ++
.../net/shibboleth/idp/module/views/admin/hello.vm | 1 +
.../idp/module/views/admin/unlock-keys.vm | 1 +
.../views/client-storage/client-storage-read.vm | 15 ++++++----
.../views/client-storage/client-storage-write.vm | 15 ++++++----
.../net/shibboleth/idp/module/views/error.vm | 3 ++
.../module/views/intercept/attribute-release.vm | 1 +
.../module/views/intercept/expiring-password.vm | 1 +
.../idp/module/views/intercept/impersonate.vm | 1 +
.../idp/module/views/intercept/terms-of-use.vm | 1 +
.../net/shibboleth/idp/module/views/login.vm | 7 +++--
.../shibboleth/idp/module/views/logout-complete.vm | 3 ++
.../idp/module/views/logout-propagate.vm | 3 ++
.../net/shibboleth/idp/module/views/logout.vm | 3 ++
.../idp/module/views/spnego-unavailable.vm | 6 +++-
.../net/shibboleth/idp/module/views/user-prefs.js | 2 ++
.../net/shibboleth/idp/module/views/user-prefs.vm | 18 +++++++-----
.../shibboleth/idp/views/client-storage/read.vm | 6 ++--
.../shibboleth/idp/views/client-storage/write.vm | 4 ++-
.../net/shibboleth/idp/views/logout/propagate.vm | 4 ++-
.../net/shibboleth/idp/views/logout/saml-async.vm | 1 +
44 files changed, 195 insertions(+), 34 deletions(-)
diff --git a/idp-authn-impl/pom.xml b/idp-authn-impl/pom.xml
index 53b0f3f55..c763c2a88 100644
--- a/idp-authn-impl/pom.xml
+++ b/idp-authn-impl/pom.xml
@@ -104,6 +104,10 @@
<groupId>${shib-shared.groupId}</groupId>
<artifactId>shib-networking</artifactId>
</dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-security</artifactId>
+ </dependency>
<dependency>
<groupId>${shib-shared.groupId}</groupId>
<artifactId>shib-service</artifactId>
@@ -264,11 +268,6 @@
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>${shib-shared.groupId}</groupId>
- <artifactId>shib-security</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>${shib-shared.groupId}</groupId>
<artifactId>shib-testing</artifactId>
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnController.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnController.java
index f9484960f..43e677fb6 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnController.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/spnego/impl/SPNEGOAuthnController.java
@@ -43,8 +43,9 @@ import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.codec.HTMLEncoder;
+import net.shibboleth.shared.codec.StringDigester;
import net.shibboleth.shared.primitive.LoggerFactory;
-
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@@ -70,6 +71,34 @@ public class SPNEGOAuthnController {
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(SPNEGOAuthnController.class);
+
+ /** CSP digest computation bean. */
+ @Nullable private StringDigester cspDigester;
+
+ /** CSP nonce generator bean. */
+ @Nullable private IdentifierGenerationStrategy cspNonceGenerator;
+
+ /**
+ * Sets a {@link StringDigester} to use in computing CSP digests in views.
+ *
+ * @param digester digester to set
+ *
+ * @since 5.1.0
+ */
+ public void setCSPDigester(@Nullable final StringDigester digester) {
+ cspDigester = digester;
+ }
+
+ /**
+ * Sets an {@link IdentifierGenerationStrategy} to use in computing CSP nonces in views.
+ *
+ * @param strategy nonce strategy
+ *
+ * @since 5.1.0
+ */
+ public void setCSPNonceGenerator(@Nullable final IdentifierGenerationStrategy strategy) {
+ cspNonceGenerator = strategy;
+ }
/**
* Handle initial request that starts SPNEGO.
@@ -390,6 +419,8 @@ public class SPNEGOAuthnController {
modelAndView.addObject("request", httpRequest);
modelAndView.addObject("response", httpResponse);
modelAndView.addObject("encoder", HTMLEncoder.class);
+ modelAndView.addObject("cspDigester", cspDigester);
+ modelAndView.addObject("cspNonce", cspNonceGenerator);
final StringBuffer errorUrl = httpRequest.getRequestURL();
errorUrl.append("/error");
final String queryString = httpRequest.getQueryString();
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/mvc-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/mvc-beans.xml
index 86e2104f7..35e087f1c 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/mvc-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/mvc-beans.xml
@@ -56,7 +56,9 @@
<!-- Additional MVC controllers scanned for annotations. -->
- <bean id="shibboleth.SPNEGOAuthnController" class="net.shibboleth.idp.authn.spnego.impl.SPNEGOAuthnController" />
+ <bean id="shibboleth.SPNEGOAuthnController" class="net.shibboleth.idp.authn.spnego.impl.SPNEGOAuthnController"
+ p:cSPDigester-ref="shibboleth.CSPDigester"
+ p:cSPNonceGenerator-ref="shibboleth.CSPNonce" />
<bean id="shibboleth.SAMLAuthnPOSTController" class="net.shibboleth.idp.saml.saml2.profile.impl.SAMLAuthnController"
p:inboundBindings-ref="shibboleth.OutgoingSAML2SSOBindings" />
<bean id="shibboleth.RaiseErrorController" class="net.shibboleth.shared.spring.error.ErrorRaisingController" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/primitives.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/primitives.xml
index 18ccdc95e..228fc03f4 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/primitives.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/primitives.xml
@@ -49,6 +49,31 @@
<bean id="shibboleth.X509TrustManager" abstract="true"
class="org.opensaml.security.trust.impl.TrustEngineX509TrustManager" />
+ <!-- Used in views to calculate CSP hashes and nonces. -->
+
+ <bean id="shibboleth.CSPDigester" class="net.shibboleth.shared.codec.StringDigester"
+ c:algorithm="SHA256" c:format="BASE64" />
+
+ <bean id="shibboleth.CSPNonce" destroy-method=""
+ class="net.shibboleth.shared.security.IdentifierGenerationStrategy" factory-method="getInstance">
+ <constructor-arg>
+ <util:constant
+ static-field="net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType.SECURE" />
+ </constructor-arg>
+ <constructor-arg>
+ <bean class="net.shibboleth.shared.security.RandomIdentifierParameterSpec"
+ c:identifierSize="16">
+ <constructor-arg name="source">
+ <null/>
+ </constructor-arg>
+ <constructor-arg name="identifierEncoder">
+ <null/>
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+
<!-- Beans for user-visible metadata configuration usage. -->
<!-- Secondary indexing support -->
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/hello-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/hello-flow.xml
index aba96d022..b71d8e7d8 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/hello-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/hello-flow.xml
@@ -34,6 +34,8 @@
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.SubjectContext))" result="requestScope.subjectContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.profile.context.RelyingPartyContext)).getSubcontext(T(net.shibboleth.idp.attribute.context.AttributeContext))" result="requestScope.attributeContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/mdquery-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/mdquery-flow.xml
index e1e7bb02e..4f2c4cf47 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/mdquery-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/mdquery-flow.xml
@@ -44,6 +44,8 @@
<evaluate expression="T(org.opensaml.core.xml.util.XMLObjectSupport)" result="requestScope.XMLObjectSupport" />
<evaluate expression="T(net.shibboleth.shared.xml.SerializeSupport)" result="requestScope.SerializeSupport" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/resolvertest-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/resolvertest-flow.xml
index 0619eadbe..f241a59dc 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/resolvertest-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/resolvertest-flow.xml
@@ -103,6 +103,8 @@
<evaluate expression="T(org.opensaml.core.xml.util.XMLObjectSupport)" result="requestScope.XMLObjectSupport" />
<evaluate expression="T(net.shibboleth.shared.xml.SerializeSupport)" result="requestScope.SerializeSupport" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/status-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/status-flow.xml
index cd8d76ffe..ddb4e075b 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/status-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/status-flow.xml
@@ -34,6 +34,8 @@
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.metrics.MetadataGaugeSet')" result="requestScope.metadataResolverGaugeSet" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/unlock-keys-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/unlock-keys-flow.xml
index 7f79ddf3e..e92bffffc 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/unlock-keys-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/unlock-keys-flow.xml
@@ -37,6 +37,8 @@
<evaluate expression="environment" result="viewScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="viewScope.custom" />
@@ -64,6 +66,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-flow.xml
index 0d1ae192e..c5b103849 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-flow.xml
@@ -33,6 +33,8 @@
<evaluate expression="authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationWarningContext))" result="viewScope.authenticationWarningContext" />
<evaluate expression="authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.LDAPResponseContext))" result="viewScope.ldapResponseContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="viewScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/cas/cas-abstract-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/cas/cas-abstract-flow.xml
index fa3957f03..d2b5b7e43 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/cas/cas-abstract-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/cas/cas-abstract-flow.xml
@@ -33,6 +33,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-read-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-read-flow.xml
index f5a19a2cd..22c1aef1a 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-read-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-read-flow.xml
@@ -16,6 +16,8 @@
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(org.opensaml.storage.impl.client.ClientStorageLoadContext))" result="viewScope.loadContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
</on-render>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-write-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-write-flow.xml
index b5af21831..31367fd0e 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-write-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/client-storage/client-storage-write-flow.xml
@@ -16,6 +16,8 @@
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(org.opensaml.storage.impl.client.ClientStorageSaveContext))" result="viewScope.saveContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
</on-render>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/attribute-release-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/attribute-release-flow.xml
index 2ee911084..262e8e9a9 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/attribute-release-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/attribute-release-flow.xml
@@ -122,6 +122,8 @@
<on-render>
<evaluate expression="environment" result="viewScope.environment" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/expiring-password-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/expiring-password-flow.xml
index 73c79e4ea..4fb754f79 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/expiring-password-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/expiring-password-flow.xml
@@ -33,6 +33,8 @@
<evaluate expression="ExpiringPasswordCookieManager.addCookie(ExpiringPasswordCookieName, T(java.lang.Long).toString(T(java.lang.System).currentTimeMillis()))" />
<evaluate expression="environment" result="viewScope.environment" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/impersonate-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/impersonate-flow.xml
index f97451464..06f522ddd 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/impersonate-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/impersonate-flow.xml
@@ -22,6 +22,8 @@
<on-render>
<evaluate expression="environment" result="viewScope.environment" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/terms-of-use-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/terms-of-use-flow.xml
index f55302956..48868529d 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/terms-of-use-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/terms-of-use-flow.xml
@@ -30,9 +30,11 @@
<view-state id="DisplayTermsOfUsePage" view="#{flowRequestContext.activeFlow.id}">
<on-render>
<evaluate expression="environment" result="viewScope.environment" />
+ <evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
- <evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
<evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).getSubcontext(T(net.shibboleth.idp.ui.context.RelyingPartyUIContext))" result="viewScope.rpUIContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.consent.context.ConsentContext)).getCurrentConsents().keySet().iterator().next()" result="viewScope.termsOfUseId" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="viewScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/warning-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/warning-flow.xml
index 90a7806ac..8ec542c50 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/warning-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/intercept/warning-flow.xml
@@ -45,6 +45,8 @@
<evaluate expression="WarningCookieManager.addCookie(WarningCookieName, T(java.lang.Long).toString(T(java.lang.System).currentTimeMillis()))" />
<evaluate expression="environment" result="viewScope.environment" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-flow.xml
index d160440b7..0ad62af6d 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-flow.xml
@@ -97,6 +97,8 @@
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.session.context.LogoutContext))" result="viewScope.logoutContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.profile.context.MultiRelyingPartyContext))" result="viewScope.multiRPContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="viewScope.custom" />
@@ -129,6 +131,8 @@
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.htmlEncoder" />
<evaluate expression="T(java.net.URLEncoder)" result="requestScope.urlEncoder" />
<evaluate expression="T(org.cryptacular.util.CodecUtil)" result="requestScope.codecUtil" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.LogoutPropagationFlowSelector')" result="requestScope.flowSelector" />
@@ -144,6 +148,8 @@
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.session.context.LogoutContext))" result="requestScope.logoutContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.profile.context.MultiRelyingPartyContext))" result="requestScope.multiRPContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
@@ -178,6 +184,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
@@ -190,6 +198,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-propagation-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-propagation-flow.xml
index 1cb71ca3b..bbdb0090e 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-propagation-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/logout/logout-propagation-flow.xml
@@ -39,6 +39,8 @@
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.UserAgentContext))" result="requestScope.userAgentContext" />
<evaluate expression="externalContext.nativeResponse.setContentType('application/json')" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="WriteAuditLog" />
</on-entry>
</end-state>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml-abstract-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml-abstract-flow.xml
index e7c33b785..0d9c4bbc5 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml-abstract-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml-abstract-flow.xml
@@ -163,6 +163,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
@@ -175,6 +177,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-back-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-back-flow.xml
index 293aac38d..92eb7bc4d 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-back-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-back-flow.xml
@@ -101,6 +101,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-front-abstract-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-front-abstract-flow.xml
index b26d7272a..3b7a76e93 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-front-abstract-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/saml2/slo-front-abstract-flow.xml
@@ -141,6 +141,8 @@
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.session.context.LogoutContext))" result="viewScope.logoutContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.profile.context.MultiRelyingPartyContext))" result="viewScope.multiRPContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="viewScope.custom" />
@@ -172,6 +174,8 @@
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.htmlEncoder" />
<evaluate expression="T(java.net.URLEncoder)" result="viewScope.urlEncoder" />
<evaluate expression="T(org.cryptacular.util.CodecUtil)" result="viewScope.codecUtil" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.LogoutPropagationFlowSelector')" result="viewScope.flowSelector" />
@@ -189,6 +193,8 @@
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.session.context.LogoutContext))" result="viewScope.logoutContext" />
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.profile.context.MultiRelyingPartyContext))" result="viewScope.multiRPContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="viewScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="viewScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="viewScope.custom" />
@@ -248,6 +254,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
@@ -260,6 +268,8 @@
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/flows/user/prefs/prefs-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/flows/user/prefs/prefs-flow.xml
index 723f360be..3e6efae99 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/flows/user/prefs/prefs-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/flows/user/prefs/prefs-flow.xml
@@ -17,6 +17,8 @@
<on-entry>
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="requestScope.request" />
<evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="requestScope.response" />
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.CustomViewContext') ? flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CustomViewContext') : null" result="requestScope.custom" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/hello.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/hello.vm
index 6268c6c94..67dc673b5 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/hello.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/hello.vm
@@ -12,6 +12,7 @@
## environment - Spring Environment object for property resolution
## custom - arbitrary object injected by deployer
##
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/unlock-keys.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/unlock-keys.vm
index 23317bc50..a124a62b4 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/unlock-keys.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/admin/unlock-keys.vm
@@ -13,6 +13,7 @@
#set ($titleSuffix = $springMacroRequestContext.getMessage("idp.unlock-keys.title", "Attended Restart Key Unlock"))
#set ($eventId = $profileRequestContext.getSubcontext("org.opensaml.profile.context.EventContext").getEvent())
#set ($state = $flowRequestContext.getCurrentState().getId())
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-read.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-read.vm
index 1afe818d0..8bfe9a299 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-read.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-read.vm
@@ -8,12 +8,19 @@
## profileRequestContext - root of context tree
## loadContext - context with details about the storage keys to load
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
#set ($title = $springMacroRequestContext.getMessage("idp.title", "Web Login Service"))
#set ($titleSuffix = $springMacroRequestContext.getMessage("idp.client-storage-read.suffix", "Loading Session Information"))
##
+#set ($onLoad = "doLoad()")
+$response.setHeader("Content-Security-Policy", "script-src-attr 'unsafe-hashes' 'sha256-$cspDigester.apply($onLoad)'")
+## Nonce for dynanmic scripts.
+#set ($nonce = $cspNonce.generateIdentifier())
+$response.setHeader("Content-Security-Policy", "script-src-elem 'nonce-$nonce'")
<!DOCTYPE html>
<html>
<head>
@@ -22,13 +29,9 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("idp.css", "/css/placeholder.css")">
- <script>
- <!--
- #include("client-storage/local-storage-read.js")
- // -->
- </script>
+ <script nonce="$nonce"><!-- #include("client-storage/local-storage-read.js") // --></script>
</head>
- <body onload="doLoad()">
+ <body onload="$onLoad">
<main class="main">
<section>
<h1>$title - $titleSuffix</h1>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-write.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-write.vm
index 066cbdbc1..f03a249ef 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-write.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/client-storage/client-storage-write.vm
@@ -8,12 +8,19 @@
## profileRequestContext - root of context tree
## saveContext - context with details about the storage data to save
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
#set ($title = $springMacroRequestContext.getMessage("idp.title", "Web Login Service"))
#set ($titleSuffix = $springMacroRequestContext.getMessage("idp.client-storage-write.suffix", "Saving Session Information..."))
##
+#set ($onLoad = "doSave()")
+$response.setHeader("Content-Security-Policy", "script-src-attr 'unsafe-hashes' 'sha256-$cspDigester.apply($onLoad)'")
+## Nonce for dynanmic scripts.
+#set ($nonce = $cspNonce.generateIdentifier())
+$response.setHeader("Content-Security-Policy", "script-src-elem 'nonce-$nonce'")
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
@@ -22,13 +29,9 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("idp.css", "/css/placeholder.css")">
- <script>
- <!--
- #include("client-storage/local-storage-write.js")
- // -->
- </script>
+ <script nonce="$nonce"><!-- #include("client-storage/local-storage-write.js") // --></script>
</head>
- <body onload="doSave()">
+ <body onload="$onLoad">
<main class="main">
<section>
<h1>$title - $titleSuffix</h1>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/error.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/error.vm
index 0f01e89f7..f3b53c419 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/error.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/error.vm
@@ -8,6 +8,8 @@
## flowRequestContext - the Spring Web Flow RequestContext
## profileRequestContext - root of context tree
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -45,6 +47,7 @@
$response.setStatus(500)
#end
##
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/attribute-release.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/attribute-release.vm
index db103833e..32f9e30f7 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/attribute-release.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/attribute-release.vm
@@ -25,6 +25,7 @@
#set ($rpOrganizationName = $rpUIContext.organizationDisplayName)
#set ($replaceDollarWithNewline = true)
##
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/expiring-password.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/expiring-password.vm
index f0ecc4d94..4523ab4c9 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/expiring-password.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/expiring-password.vm
@@ -16,6 +16,7 @@
## environment - Spring Environment object for property resolution
## custom - arbitrary object injected by deployer
##
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/impersonate.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/impersonate.vm
index 296cd197c..8e4b40786 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/impersonate.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/impersonate.vm
@@ -14,6 +14,7 @@
## custom - arbitrary object injected by deployer
##
#set ($rpContext = $profileRequestContext.getSubcontext('net.shibboleth.profile.context.RelyingPartyContext'))
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/terms-of-use.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/terms-of-use.vm
index 9d43c2a4c..c3a0460d2 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/terms-of-use.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/intercept/terms-of-use.vm
@@ -15,6 +15,7 @@
#set ($serviceName = $rpUIContext.serviceName)
#set ($rpOrganizationLogo = $rpUIContext.getLogo())
##
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login.vm
index 20ed38ea0..2ed0cd253 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login.vm
@@ -12,6 +12,8 @@
## ldapResponseContext - context with LDAP state (if using native LDAP)
## rpUIContext - the context with SP UI information from the metadata
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -20,6 +22,8 @@
#set ($rpContext = $profileRequestContext.getSubcontext('net.shibboleth.profile.context.RelyingPartyContext'))
#set ($username = $authenticationContext.getSubcontext('net.shibboleth.idp.authn.context.UsernamePasswordContext', true).getUsername())
##
+#set ($onClick = "this.childNodes[0].nodeValue='#springMessageText('idp.login.pleasewait', 'Logging in, please wait...')'")
+$response.setHeader("Content-Security-Policy", "script-src-attr 'unsafe-hashes' 'sha256-$cspDigester.apply($onClick)'")
<!DOCTYPE html>
<html>
<head>
@@ -84,8 +88,7 @@
<div class="grid">
<div class="grid-item">
- <button type="submit" name="_eventId_proceed"
- onClick="this.childNodes[0].nodeValue='#springMessageText("idp.login.pleasewait", "Logging in, please wait...")'"
+ <button type="submit" name="_eventId_proceed" onClick="$onClick"
>#springMessageText("idp.login.login", "Login")</button>
</div>
</div>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-complete.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-complete.vm
index 2d332eac7..93e9ac9ea 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-complete.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-complete.vm
@@ -9,6 +9,8 @@
## logoutContext - context with SPSession details for logout operation
## multiRPContext - context with RelyingPartyContexts and possibly SP UI information from the metadata
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -16,6 +18,7 @@
##
#set ($activeIdPSessions = $logoutContext and !$logoutContext.getIdPSessions().isEmpty())
#set ($activeSPSessions = $logoutContext and !$logoutContext.getSessionMap().isEmpty())
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-propagate.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-propagate.vm
index ab733829c..675968882 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-propagate.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout-propagate.vm
@@ -10,6 +10,8 @@
## multiRPContext - context with RelyingPartyContexts and possibly SP UI information from the metadata
## htmlEncoder - HTMLEncoder class
## urlEncoder - urlEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## codecUtil - CodecUtil class
## request - HttpServletRequest
## response - HttpServletResponse
@@ -17,6 +19,7 @@
## custom - arbitrary object injected by deployer
##
#set ($hidden = $environment.getProperty("idp.logout.propagationHidden", "false"))
+$response.setHeader("Content-Security-Policy", "script-src 'unsafe-inline' 'self'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout.vm
index ab0160064..dc2397cb0 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/logout.vm
@@ -9,6 +9,8 @@
## logoutContext - context with SPSession details for logout operation
## multiRPContext - context with RelyingPartyContexts and possibly SP UI information from the metadata
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -20,6 +22,7 @@
#end
#set ($promptForIdP = $logoutContext and !$logoutContext.getIdPSessions().isEmpty())
#set ($promptForSP = $logoutContext and !$logoutContext.getSessionMap().isEmpty())
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/spnego-unavailable.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/spnego-unavailable.vm
index ee6f17b52..6fed743b6 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/spnego-unavailable.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/spnego-unavailable.vm
@@ -6,12 +6,16 @@
##
## Velocity context will contain the following properties
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## profileRequestContext - root of context tree
## errorUrl - URL to call to indicate error and return back to the login flow
##
#set ($eventKey = $springMacroRequestContext.getMessage("SPNEGOUnavailable", "spnego-unavailable"))
+#set ($onLoad = "window.location = '$errorUrl'")
+$response.setHeader("Content-Security-Policy", "script-src-attr 'unsafe-hashes' 'sha256-$cspDigester.apply($onLoad)'")
<!DOCTYPE html>
<html>
<head>
@@ -21,7 +25,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("idp.css", "/css/placeholder.css")">
</head>
- <body onload="window.location = '$errorUrl'">
+ <body onLoad="$onLoad">
<main class="main">
<header>
<img class="main-logo" src="$request.getContextPath()#springMessageText("idp.logo", "/images/placeholder-logo.png")" alt="#springMessageText("idp.logo.alt-text", "logo")">
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.js b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.js
index ab994f9a9..81f143a61 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.js
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.js
@@ -1,3 +1,4 @@
+<!--
"use strict";
function createCookie(name, value, seconds) {
@@ -43,3 +44,4 @@ function check(checkbox) {
eraseCookie(checkbox.name);
}
}
+// -->
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.vm
index 8f70837d2..d790ddb1a 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/user-prefs.vm
@@ -6,7 +6,15 @@
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
## custom - arbitrary object injected by deployer
+## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
##
+#set ($onLoad = "load('spnego')")
+#set ($onClick = "check(this)")
+$response.setHeader("Content-Security-Policy", "script-src-attr 'unsafe-hashes' 'sha256-$cspDigester.apply($onLoad)','sha256-$cspDigester.apply($onClick)'")
+## Hash of user-prefs.js (being injected inline below).
+$response.setHeader("Content-Security-Policy", "script-src-elem 'unsafe-hashes' 'sha256-mXQMhpzvwZ/f5iKzcm/iFe50L/0b7cNjsvcFVu/PMTg='")
<!DOCTYPE html>
<html>
<head>
@@ -15,14 +23,10 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("idp.css", "/css/placeholder.css")">
- <script language="Javascript">
- <!--
- #parse( "user-prefs.js" )
- // -->
- </script>
+ <script language="Javascript">#parse("user-prefs.js")</script>
</head>
- <body onLoad="document.getElementById('content').style.display='block'; load('spnego')">
+ <body onLoad="$onLoad">
<main class="main">
<header>
<img class="main-logo" src="$request.getContextPath()#springMessageText("idp.logo", "/images/placeholder-logo.png")" alt="#springMessageText("idp.logo.alt-text", "logo")">
@@ -41,7 +45,7 @@
<form>
<p>#springMessageText("idp.userprefs.options", "The following options are available:")</p>
- <input type="checkbox" id="spnego" name="_idp_spnego_autologin" value="1" onClick="check(this)">
+ <input type="checkbox" id="spnego" name="_idp_spnego_autologin" value="1" onClick="$onClick">
<label for="spnego"> #springMessageText("idp.userprefs.spnego", "Automatically try desktop login when available.")</label>
</form>
</section>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/read.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/read.vm
index fc514d695..6a42fded0 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/read.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/read.vm
@@ -8,6 +8,8 @@
## profileRequestContext - root of context tree
## loadContext - context with details about the storage keys to load
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -29,7 +31,7 @@
</noscript>
</form>
-<script>
+<script #if ($nonce)nonce="$nonce"#end>
<!--
function doLoad() {
var localStorageSupported = isLocalStorageSupported();
@@ -42,4 +44,4 @@ function doLoad() {
document.form1.submit();
}
// -->
-</script>
\ No newline at end of file
+</script>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/write.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/write.vm
index b059100ca..008ebec11 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/write.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/client-storage/write.vm
@@ -8,6 +8,8 @@
## profileRequestContext - root of context tree
## saveContext - context with details about the storage data to save
## encoder - HTMLEncoder class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -28,7 +30,7 @@
</noscript>
</form>
-<script>
+<script #if ($nonce)nonce="$nonce"#end>
<!--
function doSave() {
#foreach ($op in $saveContext.getStorageOperations())
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/propagate.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/propagate.vm
index 58a2d4186..34db86bf0 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/propagate.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/propagate.vm
@@ -12,6 +12,8 @@
## htmlEncoder - HTMLEncoder class
## urlEncoder - urlEncoder class
## codecUtil - CodecUtil class
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply)
+## cspNonce - Calculates secure nonces (call generateIdentifier)
## request - HttpServletRequest
## response - HttpServletResponse
## environment - Spring Environment object for property resolution
@@ -47,7 +49,7 @@
title="$logoutTitle">$htmlEncoder.encodeForHTML($serviceName)</li>
#end
</ol>
- <script src="$request.getContextPath()/js/jquery-3.6.0.min.js"></script>
+ <script src="$request.getContextPath()/js/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="></script>
<script>
<!--
function check_status() {
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/saml-async.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/saml-async.vm
index adb519649..836f51251 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/saml-async.vm
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/views/logout/saml-async.vm
@@ -9,6 +9,7 @@
## environment - Spring Environment object for property resolution
## custom - arbitrary object injected by deployer
##
+$response.setHeader("Content-Security-Policy", "script-src 'none'")
<!DOCTYPE html>
<html>
<head>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list