You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2012/07/24 10:08:51 UTC
svn commit: r1364930 - in /myfaces/tobago/trunk:
tobago-core/src/main/java/org/apache/myfaces/tobago/config/
tobago-core/src/main/java/org/apache/myfaces/tobago/context/
tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/
tobago-core/s...
Author: lofwyr
Date: Tue Jul 24 08:08:50 2012
New Revision: 1364930
URL: http://svn.apache.org/viewvc?rev=1364930&view=rev
Log:
TOBAGO-1171: Support for the Content Security Policy (CSP)
- you can switch CSP on in the tobago-config.xml (please do that only for development in the moment)
- support for different UserAgent (different header names)
still open:
- The renderers of Tobago must be refactored
Modified:
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/context/UserAgent.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ResponseUtils.java
myfaces/tobago/trunk/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-1.6.xsd
myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/PageRenderer.java
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java Tue Jul 24 08:08:50 2012
@@ -76,4 +76,6 @@ public abstract class TobagoConfig {
public abstract boolean isPreventFrameAttacks();
+ public abstract List<String> getContentSecurityPolicy();
+
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/context/UserAgent.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/context/UserAgent.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/context/UserAgent.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/context/UserAgent.java Tue Jul 24 08:08:50 2012
@@ -33,7 +33,6 @@ public class UserAgent implements Serial
public static final UserAgent DEFAULT = new UserAgent(null, null);
-
public static final UserAgent MSIE = new UserAgent("msie", null);
/**
@@ -65,7 +64,8 @@ public class UserAgent implements Serial
public static final UserAgent MSIE_9_0 = new UserAgent("msie", "9_0", EnumSet.of(Capability.CONTENT_TYPE_XHTML));
- public static final UserAgent MSIE_10_0 = new UserAgent("msie", "10_0", EnumSet.of(Capability.CONTENT_TYPE_XHTML));
+ public static final UserAgent MSIE_10_0
+ = new UserAgent("msie", "10_0", EnumSet.of(Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
/**
* @deprecated no longer supported, since Tobago 1.5
@@ -151,19 +151,22 @@ public class UserAgent implements Serial
* e. g. Firefox 4.0
*/
public static final UserAgent GECKO_2_0
- = new UserAgent("gecko", "2_0", EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML));
+ = new UserAgent("gecko", "2_0",
+ EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
/**
* e. g. Firefox 5.0
*/
public static final UserAgent GECKO_5_0
- = new UserAgent("gecko", "5_0", EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML));
+ = new UserAgent("gecko", "5_0",
+ EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
/**
* e. g. Safari 4, Safari 5, Chrome
*/
public static final UserAgent WEBKIT
- = new UserAgent("webkit", null, EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML));
+ = new UserAgent("webkit", null,
+ EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_WEBKIT);
private final String name;
@@ -171,14 +174,21 @@ public class UserAgent implements Serial
private final EnumSet<Capability> capabilities;
+ private final CspHeader cspHeader;
+
private UserAgent(String name, String version) {
- this(name , version, EnumSet.of(Capability.CONTENT_TYPE_XHTML));
+ this(name, version, EnumSet.of(Capability.CONTENT_TYPE_XHTML), null);
}
private UserAgent(String name, String version, EnumSet<Capability> capabilities) {
+ this(name, version, capabilities, CspHeader.CSP_NOT_SUPPORTED);
+ }
+
+ private UserAgent(String name, String version, EnumSet<Capability> capabilities, CspHeader cspHeader) {
this.name = name;
this.version = version;
this.capabilities = capabilities;
+ this.cspHeader = cspHeader;
}
public boolean hasCapability(Capability capability) {
@@ -220,6 +230,13 @@ public class UserAgent implements Serial
return list;
}
+ /**
+ * @return The HTTP header name for Content-Security-Policy.
+ */
+ public String getCspHeader() {
+ return cspHeader.getName();
+ }
+
public static UserAgent getInstance(String header) {
if (header == null) {
return DEFAULT;
@@ -282,4 +299,22 @@ public class UserAgent implements Serial
? name + '_' + version
: name;
}
+
+ private static enum CspHeader {
+
+ CSP_NOT_SUPPORTED(null),
+ CSP_GECKO("X-Content-Security-Policy"),
+ CSP_WEBKIT("X-WebKit-CSP"),
+ CSP_STANDARD("Content-Security-Policy");
+
+ private String name;
+
+ private CspHeader(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java Tue Jul 24 08:08:50 2012
@@ -122,6 +122,10 @@ public class TobagoConfigBuilder {
result.setPreventFrameAttacks(fragment.isPreventFrameAttacks());
+ for(String directive : fragment.getContentSecurityPolicy()) {
+ result.addContentSecurityPolicy(directive);
+ }
+
// theme definition
// todo
/*
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java Tue Jul 24 08:08:50 2012
@@ -41,6 +41,7 @@ public class TobagoConfigFragment {
private Boolean createSessionSecret;
private Boolean checkSessionSecret;
private boolean preventFrameAttacks = true;
+ private List<String> contentSecurityPolicy;
// todo
private List<ThemeImpl> themeDefinitions;
private URL url;
@@ -51,6 +52,7 @@ public class TobagoConfigFragment {
supportedThemeNames = new ArrayList<String>();
resourceDirs = new ArrayList<String>();
themeDefinitions = new ArrayList<ThemeImpl>();
+ contentSecurityPolicy = new ArrayList<String>();
}
public void addSupportedThemeName(String name) {
@@ -152,6 +154,14 @@ public class TobagoConfigFragment {
this.preventFrameAttacks = preventFrameAttacks;
}
+ public List<String> getContentSecurityPolicy() {
+ return contentSecurityPolicy;
+ }
+
+ public void addContentSecurityPolicy(String directive) {
+ contentSecurityPolicy.add(directive);
+ }
+
/** @deprecated since 1.5.0 */
@Deprecated
public void setFixResourceOrder(String value) {
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java Tue Jul 24 08:08:50 2012
@@ -57,6 +57,7 @@ public class TobagoConfigImpl extends To
private boolean createSessionSecret;
private boolean checkSessionSecret;
private boolean preventFrameAttacks = true;
+ private List<String> contentSecurityPolicy;
private URL url;
private Map<String, String> defaultValidatorInfo;
@@ -66,6 +67,7 @@ public class TobagoConfigImpl extends To
resourceDirs = new ArrayList<String>();
createSessionSecret = true;
checkSessionSecret = true;
+ contentSecurityPolicy = new ArrayList<String>();
}
public void addSupportedThemeName(String name) {
@@ -276,6 +278,14 @@ public class TobagoConfigImpl extends To
this.preventFrameAttacks = preventFrameAttacks;
}
+ public List<String> getContentSecurityPolicy() {
+ return contentSecurityPolicy;
+ }
+
+ public void addContentSecurityPolicy(String directive) {
+ contentSecurityPolicy.add(directive);
+ }
+
public Map<String, String> getDefaultValidatorInfo() {
// TODO: if the startup hasn't found a FacesContext and Application, this may depend on the order of the listeners.
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java Tue Jul 24 08:08:50 2012
@@ -111,8 +111,13 @@ public class TobagoConfigParser {
// session secret
digester.addCallMethod("tobago-config/create-session-secret", "setCreateSessionSecret", 0);
digester.addCallMethod("tobago-config/check-session-secret", "setCheckSessionSecret", 0);
+
+ // frame attacks
digester.addBeanPropertySetter("tobago-config/prevent-frame-attacks", "preventFrameAttacks");
+ // content-security-policy
+ digester.addCallMethod("tobago-config/content-security-policy/directive", "addContentSecurityPolicy", 0);
+
// renderer config
digester.addObjectCreate("tobago-config/renderers", RenderersConfigImpl.class);
digester.addSetNext("tobago-config/renderers", "setRenderersConfig");
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ResponseUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ResponseUtils.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ResponseUtils.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ResponseUtils.java Tue Jul 24 08:08:50 2012
@@ -17,12 +17,15 @@ package org.apache.myfaces.tobago.intern
* limitations under the License.
*/
+import org.apache.myfaces.tobago.context.ClientProperties;
+import org.apache.myfaces.tobago.context.UserAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
+import java.util.List;
public class ResponseUtils {
@@ -74,4 +77,21 @@ public class ResponseUtils {
}
}
}
+
+ public static void ensureContentSecurityPolicyHeader(FacesContext facesContext, List<String> contentSecurityPolicy) {
+ // TODO PortletRequest
+ if (facesContext.getExternalContext().getResponse() instanceof HttpServletResponse) {
+ final UserAgent userAgent = ClientProperties.getInstance(facesContext).getUserAgent();
+ final String cspHeader = userAgent.getCspHeader();
+ if (cspHeader != null) {
+ final StringBuilder value = new StringBuilder();
+ for (String directive : contentSecurityPolicy) {
+ value.append(directive);
+ value.append(";");
+ }
+ final HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
+ response.setHeader(cspHeader, value.toString());
+ }
+ }
+ }
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-1.6.xsd
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-1.6.xsd?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-1.6.xsd (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-1.6.xsd Tue Jul 24 08:08:50 2012
@@ -58,6 +58,7 @@
<xs:element name="create-session-secret" type="xs:boolean" minOccurs="0"/>
<xs:element name="check-session-secret" type="xs:boolean" minOccurs="0"/>
<xs:element name="prevent-frame-attacks" type="xs:boolean" minOccurs="0" default="true"/>
+ <xs:element name="content-security-policy" type="tobago:content-security-policy-type" minOccurs="0"/>
<xs:element name="renderers" type="tobago:renderers-type" minOccurs="0"/>
<xs:element name="theme-definitions" type="tobago:theme-definitions-type" minOccurs="0"/>
</xs:sequence>
@@ -92,6 +93,12 @@
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="content-security-policy-type">
+ <xs:sequence>
+ <xs:element name="directive" type="xs:string" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
<xs:complexType name="renderers-type">
<xs:sequence>
<xs:element name="renderer" type="tobago:renderer-type" maxOccurs="unbounded"/>
Modified: myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml (original)
+++ myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml Tue Jul 24 08:08:50 2012
@@ -20,8 +20,8 @@
<tobago-config
xmlns="http://myfaces.apache.org/tobago/tobago-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://myfaces.apache.org/tobago/tobago-config http://myfaces.apache.org/tobago/tobago-config-1.5.xsd"
- version="1.5">
+ xsi:schemaLocation="http://myfaces.apache.org/tobago/tobago-config http://myfaces.apache.org/tobago/tobago-config-1.6.xsd"
+ version="1.6">
<name>demo</name>
@@ -44,6 +44,19 @@
<resource-dir>tobago-resource</resource-dir>
+<!-- enable this to test CSP
+ <content-security-policy>
+ <directive>default-src 'self'</directive>
+ </content-security-policy>
+-->
+
+<!-- this may be an alternative way to define (not implemented)
+ <content-security-policy>
+ <default-src>'self'</default-src>
+ <image-src>images.irian.eu</image-src>
+ </content-security-policy>
+-->
+
<renderers>
<renderer>
Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/PageRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/PageRenderer.java?rev=1364930&r1=1364929&r2=1364930&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/PageRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/PageRenderer.java Tue Jul 24 08:08:50 2012
@@ -125,7 +125,8 @@ public class PageRenderer extends PageRe
@Override
public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
- UIPage page = (UIPage) component;
+ final UIPage page = (UIPage) component;
+ final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
// invoke prepareRender
RenderUtils.prepareRendererAll(facesContext, page);
@@ -142,6 +143,8 @@ public class PageRenderer extends PageRe
ResponseUtils.ensureNoCacheHeader(facesContext);
+ ResponseUtils.ensureContentSecurityPolicyHeader(facesContext, tobagoConfig.getContentSecurityPolicy());
+
if (LOG.isDebugEnabled()) {
for (Object o : page.getAttributes().entrySet()) {
Map.Entry entry = (Map.Entry) o;
@@ -158,7 +161,7 @@ public class PageRenderer extends PageRe
ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
String clientId = page.getClientId(facesContext);
final ClientProperties client = VariableResolverUtils.resolveClientProperties(facesContext);
- final ProjectStage projectStage = TobagoConfig.getInstance(facesContext).getProjectStage();
+ final ProjectStage projectStage = tobagoConfig.getProjectStage();
final boolean developmentMode = projectStage == ProjectStage.Development;
final boolean debugMode = client.isDebugMode() || developmentMode;
final boolean productionMode = !debugMode && projectStage == ProjectStage.Production;
@@ -178,7 +181,7 @@ public class PageRenderer extends PageRe
} catch (NumberFormatException e) {/* ignore; use default*/ }
}
}
- boolean frameKiller = TobagoConfig.getInstance(facesContext).isPreventFrameAttacks();
+ boolean frameKiller = tobagoConfig.isPreventFrameAttacks();
if (!FacesContextUtils.isAjax(facesContext)) {
HtmlRendererUtils.renderDojoDndSource(facesContext, component);