You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2019/12/12 17:35:27 UTC

[wicket] branch master updated: WICKET-6321 added example

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

svenmeier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ae0552  WICKET-6321 added example
0ae0552 is described below

commit 0ae05520a729b8462fcece990489105b81374629
Author: Sven Meier <sv...@apache.org>
AuthorDate: Thu Dec 12 18:27:56 2019 +0100

    WICKET-6321 added example
    
    this closes #273
---
 .../markup/head/filter/CspNonceHeaderResponse.java |  4 +-
 ...esponse.java => SubresourceHeaderResponse.java} | 51 +++++-------------
 .../wicket/examples/sri/IntegrityDemoPage.html     | 12 +++++
 .../wicket/examples/sri/IntegrityDemoPage.java     | 45 ++++++++++++++++
 .../apache/wicket/examples/sri/SriApplication.java | 61 ++++++++++++++++++++++
 .../org/apache/wicket/examples/sri/subresource.js  | 24 +++++++++
 .../apache/wicket/examples/homepage/HomePage.html  |  1 +
 wicket-examples/src/main/webapp/WEB-INF/web.xml    | 16 ++++++
 8 files changed, 174 insertions(+), 40 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
index ec72315..f2a9ce1 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
@@ -26,7 +26,7 @@ import org.apache.wicket.markup.head.ResourceAggregator;
 import org.apache.wicket.markup.html.DecoratingHeaderResponse;
 
 /**
- * Add a <em>Content Security Policy<em> (CSP) nonce to all relevant JavaScript and CSS header items.
+ * Add a <em>Content Security Policy<em> (CSP) nonce to all {@link AbstractCspHeaderItem}s.
  * <p>
  * Note: please don't forget to wrap with {@link ResourceAggregator} when setting it up with
  * {@link Application#setHeaderResponseDecorator}, otherwise dependencies will not be rendered.
@@ -80,7 +80,7 @@ public class CspNonceHeaderResponse extends DecoratingHeaderResponse
 	 * Get the <em>Content-Security-Policy</em> (CSP).
 	 * <p>
 	 * There is a variety of CSP configurations, this default implementation uses the nonce for scripts and styles
-	 * and allows <code>unsafe-eval</code> and <code>strict-dynamic</code>s (needed for Wicket Ajax).
+	 * and allows <code>strict-dynamic</code>s (needed for Wicket Ajax).
 	 * 
 	 * @param nonce
 	 *            the nonce
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/SubresourceHeaderResponse.java
similarity index 52%
copy from wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
copy to wicket-core/src/main/java/org/apache/wicket/markup/head/filter/SubresourceHeaderResponse.java
index ec72315..02887d1 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/SubresourceHeaderResponse.java
@@ -17,38 +17,30 @@
 package org.apache.wicket.markup.head.filter;
 
 import org.apache.wicket.Application;
-import org.apache.wicket.markup.head.AbstractCspHeaderItem;
 import org.apache.wicket.markup.head.HeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.ISubresourceHeaderItem;
 import org.apache.wicket.markup.head.IWrappedHeaderItem;
-import org.apache.wicket.markup.head.MetaDataHeaderItem;
 import org.apache.wicket.markup.head.ResourceAggregator;
 import org.apache.wicket.markup.html.DecoratingHeaderResponse;
 
 /**
- * Add a <em>Content Security Policy<em> (CSP) nonce to all relevant JavaScript and CSS header items.
+ * Add <em>Subresource<em> integrity and crossOrigin to all {@link ISubresourceHeaderItem}s.
+ * <p>
+ * The subclass implementation of {@link #configure(ISubresourceHeaderItem)} has to decide
+ * on how to configure the item.
  * <p>
  * Note: please don't forget to wrap with {@link ResourceAggregator} when setting it up with
  * {@link Application#setHeaderResponseDecorator}, otherwise dependencies will not be rendered.
  * 
- * @see AbstractCspHeaderItem
+ * @see ISubresourceHeaderItem
  */
-public class CspNonceHeaderResponse extends DecoratingHeaderResponse
+public abstract class SubresourceHeaderResponse extends DecoratingHeaderResponse
 {
-	private static final String CONTENT_SECURITY_POLICY = "Content-Security-Policy";
-
-	/**
-	 * Has the <em>Content-Security-Policy</em> header been rendered once.
-	 */
-	private boolean policyRendered = false;
-
-	private String nonce;
 
-	public CspNonceHeaderResponse(IHeaderResponse real, String nonce)
+	public SubresourceHeaderResponse(IHeaderResponse real)
 	{
 		super(real);
-
-		this.nonce = nonce;
 	}
 
 	@Override
@@ -59,35 +51,18 @@ public class CspNonceHeaderResponse extends DecoratingHeaderResponse
 			item = ((IWrappedHeaderItem)item).getWrapped();
 		}
 
-		if (item instanceof AbstractCspHeaderItem)
+		if (item instanceof ISubresourceHeaderItem)
 		{
-			if (policyRendered == false)
-			{
-				policyRendered = true;
-
-				String policy = getContentSecurityPolicy(nonce);
-
-				super.render(MetaDataHeaderItem.forHttpEquiv(CONTENT_SECURITY_POLICY, policy));
-			}
-
-			((AbstractCspHeaderItem)item).setNonce(nonce);
+			configure((ISubresourceHeaderItem)item);
 		}
 		
 		super.render(item);
 	}
 
 	/**
-	 * Get the <em>Content-Security-Policy</em> (CSP).
-	 * <p>
-	 * There is a variety of CSP configurations, this default implementation uses the nonce for scripts and styles
-	 * and allows <code>unsafe-eval</code> and <code>strict-dynamic</code>s (needed for Wicket Ajax).
+	 * Configure the item <em>Subresource</em>.
 	 * 
-	 * @param nonce
-	 *            the nonce
-	 * @return content security policy
+	 * @param item to configure
 	 */
-	protected String getContentSecurityPolicy(String nonce)
-	{
-		return String.format("script-src 'strict-dynamic' 'nonce-%1$s'; style-src 'nonce-%1$s';", nonce);
-	}
+	protected abstract void	configure(ISubresourceHeaderItem item);
 }
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/sri/IntegrityDemoPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/IntegrityDemoPage.html
new file mode 100644
index 0000000..37815c5
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/IntegrityDemoPage.html
@@ -0,0 +1,12 @@
+<html xmlns:wicket="http://wicket.apache.org">
+<head>
+    <title>SRI Demo</title>
+</head>
+<body>
+<wicket:extend>
+    <h3>SRI Demo</h3>
+    
+    <p id="sri">Integrity test NOT passed</p>
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/sri/IntegrityDemoPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/IntegrityDemoPage.java
new file mode 100644
index 0000000..0149275
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/IntegrityDemoPage.java
@@ -0,0 +1,45 @@
+/*
+ * 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.wicket.examples.sri;
+
+import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+
+/**
+ * Page which uses subresource integrity.
+ */
+public class IntegrityDemoPage extends WicketExamplePage
+{
+
+	public static final ResourceReference JS = new JavaScriptResourceReference(
+		IntegrityDemoPage.class, "subresource.js");
+
+	public IntegrityDemoPage()
+	{
+	}
+
+	@Override
+	public void renderHead(IHeaderResponse response)
+	{
+		super.renderHead(response);
+
+		response.render(JavaScriptHeaderItem.forReference(JS));
+	}
+}
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java
new file mode 100644
index 0000000..b7ae7ab
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java
@@ -0,0 +1,61 @@
+/*
+ * 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.wicket.examples.sri;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.examples.WicketExampleApplication;
+import org.apache.wicket.markup.head.ISubresourceHeaderItem;
+import org.apache.wicket.markup.head.JavaScriptReferenceHeaderItem;
+import org.apache.wicket.markup.head.ResourceAggregator;
+import org.apache.wicket.markup.head.filter.SubresourceHeaderResponse;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+
+public class SriApplication extends WicketExampleApplication
+{
+	@Override
+	public Class<? extends Page> getHomePage()
+	{
+		return IntegrityDemoPage.class;
+	}
+
+	@Override
+	protected void init()
+	{
+		super.init();
+
+		setHeaderResponseDecorator(
+			response -> new ResourceAggregator(new SubresourceHeaderResponse(response)
+			{
+				@Override
+				protected void configure(ISubresourceHeaderItem item)
+				{
+					if (item instanceof JavaScriptReferenceHeaderItem) {
+						ResourceReference reference = ((JavaScriptReferenceHeaderItem)item).getReference();
+						
+						if (reference.equals(IntegrityDemoPage.JS)) {
+							String algorithm = "sha384";
+							String value = "yDSj1gWA4teUdCx2/5M0RsK1jovKR0RdUeeLXKU1gRpNWevoQDGhjHEd1R6Jb+FQ";
+							item.setIntegrity(algorithm + "-" + value);
+						}
+					}
+				}
+			}));
+
+		mountPage("integritydemo", IntegrityDemoPage.class);
+	}
+}
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/sri/subresource.js b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/subresource.js
new file mode 100644
index 0000000..e0e1fa6
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/subresource.js
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+/**
+ * For any change in this file its hash has to be updated in SriApplication:
+ * 
+ * openssl dgst -sha384 -binary subresource.js | openssl base64 -A 
+ */
+document.addEventListener('DOMContentLoaded', function(event) {
+	document.querySelector("#sri").textContent = 'Integrity test passed'; 
+});
\ No newline at end of file
diff --git a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
index e0c69bf..7c050bc 100644
--- a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
+++ b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
@@ -53,6 +53,7 @@
        <tr><td align="right"><a href="videos">HTML5 Media Tags</a></td><td> - Integration for HTML5 Media Tags</td></tr>
        <tr><td align="right"><a href="websockets">Web Sockets</a></td><td> - Integration for JSR356 Web Sockets</td></tr>
        <tr><td align="right"><a href="csp/noncedemo">CSP</a></td><td> - Content Security Protection</td></tr>
+       <tr><td align="right"><a href="sri/integritydemo">SRI</a></td><td> - Subresource Integrity</td></tr>
    	</tbody>
 	</table>
 </wicket:extend>	
diff --git a/wicket-examples/src/main/webapp/WEB-INF/web.xml b/wicket-examples/src/main/webapp/WEB-INF/web.xml
index 4364eeb..dd51470 100644
--- a/wicket-examples/src/main/webapp/WEB-INF/web.xml
+++ b/wicket-examples/src/main/webapp/WEB-INF/web.xml
@@ -267,6 +267,15 @@
 	</filter>
 
 	<filter>
+		<filter-name>SriApplication</filter-name>
+		<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+		<init-param>
+			<param-name>applicationClassName</param-name>
+			<param-value>org.apache.wicket.examples.sri.SriApplication</param-value>
+		</init-param>
+	</filter>
+
+	<filter>
 		<filter-name>RepeaterExamplesApplication</filter-name>
 		<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
 		<init-param>
@@ -661,6 +670,13 @@
 	</filter-mapping>
 
 	<filter-mapping>
+		<filter-name>SriApplication</filter-name>
+		<url-pattern>/sri/*</url-pattern>
+		<dispatcher>REQUEST</dispatcher>
+		<dispatcher>INCLUDE</dispatcher>
+	</filter-mapping>
+
+	<filter-mapping>
 		<filter-name>FramesApplication</filter-name>
 		<url-pattern>/frames/*</url-pattern>
 	</filter-mapping>