You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by pa...@apache.org on 2020/01/17 21:26:57 UTC
[wicket] 02/08: WICKET-6727: refactoring of CSP API
This is an automated email from the ASF dual-hosted git repository.
papegaaij pushed a commit to branch csp-configurable
in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 3bed1e9e4cd489588f00562557f5332390601340
Author: Emond Papegaaij <em...@topicus.nl>
AuthorDate: Wed Jan 15 11:20:47 2020 +0100
WICKET-6727: refactoring of CSP API
---
.../wicket/csp/CSPSettingRequestCycleListener.java | 300 +++++++++------------
.../csp/CSPSettingRequestCycleListenerTest.java | 58 ++--
2 files changed, 160 insertions(+), 198 deletions(-)
diff --git a/wicket-core/src/main/java/org/apache/wicket/csp/CSPSettingRequestCycleListener.java b/wicket-core/src/main/java/org/apache/wicket/csp/CSPSettingRequestCycleListener.java
index a32af03..47c6cdd 100644
--- a/wicket-core/src/main/java/org/apache/wicket/csp/CSPSettingRequestCycleListener.java
+++ b/wicket-core/src/main/java/org/apache/wicket/csp/CSPSettingRequestCycleListener.java
@@ -5,6 +5,7 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.EnumMap;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -311,201 +312,176 @@ public class CSPSettingRequestCycleListener implements IRequestCycleListener
private enum CSPHeaderMode
{
- BLOCKING,
- REPORT_ONLY;
- }
+ BLOCKING("Content-Security-Policy"),
+ REPORT_ONLY("Content-Security-Policy-Report-Only");
- private static String HEADER_CSP = "Content-Security-Policy";
+ private final String header;
- private static String HEADER_CSP_REPORT = "Content-Security-Policy-Report-Only";
+ private CSPHeaderMode(String header)
+ {
+ this.header = header;
+ }
- private static String HEADER_CSP_IE = "X-Content-Security-Policy";
+ public String getHeader()
+ {
+ return header;
+ }
- private static String HEADER_CSP_REPORT_IE = "X-Content-Security-Policy-Report-Only";
+ public String getLegacyHeader()
+ {
+ return "X-" + getHeader();
+ }
+ }
- // Directives for the 'Content-Security-Policy' header
- private Map<CSPDirective, List<CSPRenderable>> blockingDirectives =
- new EnumMap<>(CSPDirective.class);
+ public class CSPConfiguration
+ {
+ private CSPHeaderMode mode;
- // Directives for the 'Content-Security-Policy-Report-Only' header
- private Map<CSPDirective, List<CSPRenderable>> reportingDirectives =
- new EnumMap<>(CSPDirective.class);
+ private Map<CSPDirective, List<CSPRenderable>> directives =
+ new EnumMap<>(CSPDirective.class);
- private Function<Integer, byte[]> randomSupplier;
+ private boolean addLegacyHeaders = false;
- private boolean addLegacyHeaders = false;
+ private CSPConfiguration(CSPHeaderMode mode)
+ {
+ this.mode = mode;
+ }
- public CSPSettingRequestCycleListener()
- {
- }
+ public CSPHeaderMode getMode()
+ {
+ return mode;
+ }
- public CSPSettingRequestCycleListener(Function<Integer, byte[]> randomSupplier)
- {
- this.randomSupplier = randomSupplier;
- }
+ /**
+ * True when legacy headers should be added.
+ *
+ * @return True when legacy headers should be added.
+ */
+ public boolean isAddLegacyHeaders()
+ {
+ return addLegacyHeaders;
+ }
- /**
- * True when legacy headers should be added.
- *
- * @return True when legacy headers should be added.
- */
- public boolean isAddLegacyHeaders()
- {
- return addLegacyHeaders;
- }
+ /**
+ * Enable legacy {@code X-Content-Security-Policy} headers for older browsers, such as IE.
+ *
+ * @param addLegacyHeaders
+ * True when the legacy headers should be added.
+ * @return {@code this} for chaining
+ */
+ public CSPConfiguration setAddLegacyHeaders(boolean addLegacyHeaders)
+ {
+ this.addLegacyHeaders = addLegacyHeaders;
+ return this;
+ }
- /**
- * Enable legacy {@code X-Content-Security-Policy} headers for older browsers, such as IE.
- *
- * @param addLegacyHeaders True when the legacy headers should be added.
- * @return {@code this} for chaining
- */
- public CSPSettingRequestCycleListener setAddLegacyHeaders(boolean addLegacyHeaders)
- {
- this.addLegacyHeaders = addLegacyHeaders;
- return this;
- }
+ public CSPConfiguration addDirective(CSPDirective directive, CSPDirectiveSrcValue... values)
+ {
+ for (CSPDirectiveSrcValue value : values)
+ {
+ doAddDirective(directive, value);
+ }
+ return this;
+ }
- /**
- * Adds any of the default values to a -src directive for the 'blocking' CSP header
- */
- public CSPSettingRequestCycleListener addBlockingDirective(CSPDirective directive,
- CSPDirectiveSrcValue... values)
- {
- for (CSPDirectiveSrcValue value : values)
+ /**
+ * Adds any of the default values to the sandbox directive for the 'blocking' CSP header.
+ * Use {@link #addBlockingDirective(CSPDirective, String...)} with the sandbox
+ * {@link CSPDirective} and a single empty string (<em>not</em> {@code null}) to add the
+ * empty sandbox directive.
+ */
+ public CSPConfiguration addDirective(CSPDirective sandboxDirective,
+ CSPDirectiveSandboxValue... values)
{
- addDirective(directive, value, CSPHeaderMode.BLOCKING);
+ for (CSPDirectiveSandboxValue value : values)
+ {
+ doAddDirective(sandboxDirective, value);
+ }
+ return this;
}
- return this;
- }
- /**
- * Adds any of the default values to the sandbox directive for the 'blocking' CSP header. Use
- * {@link #addBlockingDirective(CSPDirective, String...)} with the sandbox {@link CSPDirective}
- * and a single empty string (<em>not</em> {@code null}) to add the empty sandbox directive.
- */
- public CSPSettingRequestCycleListener addBlockingDirective(CSPDirective sandboxDirective,
- CSPDirectiveSandboxValue... values)
- {
- for (CSPDirectiveSandboxValue value : values)
+ /**
+ * Adds any value to a directive for the 'blocking' CSP header. Use
+ * {@link #addBlockingDirective(CSPDirective, CSPDirectiveSandboxValue...)} and
+ * {@link #addBlockingDirective(CSPDirective, CSPDirectiveSrcValue...)} for the default
+ * values for the sandbox and -src directives.
+ */
+ public CSPConfiguration addDirective(CSPDirective directive, String... values)
{
- addDirective(sandboxDirective, value, CSPHeaderMode.BLOCKING);
+ for (String value : values)
+ {
+ doAddDirective(directive, new FixedCSPDirective(value));
+ }
+ return this;
}
- return this;
- }
- /**
- * Adds any value to a directive for the 'blocking' CSP header. Use
- * {@link #addBlockingDirective(CSPDirective, CSPDirectiveSandboxValue...)} and
- * {@link #addBlockingDirective(CSPDirective, CSPDirectiveSrcValue...)} for the default values
- * for the sandbox and -src directives.
- */
- public CSPSettingRequestCycleListener addBlockingDirective(CSPDirective directive,
- String... values)
- {
- for (String value : values)
+ public boolean isSet()
{
- addDirective(directive, new FixedCSPDirective(value), CSPHeaderMode.BLOCKING);
+ return !directives.isEmpty();
}
- return this;
- }
- /**
- * Adds any of the default values to a -src directive for the 'reporting-only' CSP header
- */
- public CSPSettingRequestCycleListener addReportingDirective(CSPDirective directive,
- CSPDirectiveSrcValue... values)
- {
- for (CSPDirectiveSrcValue value : values)
+ private CSPConfiguration doAddDirective(CSPDirective directive, CSPRenderable value)
{
- addDirective(directive, value, CSPHeaderMode.REPORT_ONLY);
+ // Add backwards compatible frame-src
+ // see http://caniuse.com/#feat=contentsecuritypolicy2
+ if (CSPDirective.CHILD_SRC.equals(directive))
+ {
+ doAddDirective(CSPDirective.FRAME_SRC, value);
+ }
+ List<CSPRenderable> values =
+ directives.computeIfAbsent(directive, x -> new ArrayList<>());
+ directive.checkValueForDirective(value, values);
+ values.add(value);
+ return this;
}
- return this;
- }
- /**
- * Adds any of the default values to the sandbox directive for the 'reporting-only' CSP header.
- * Use {@link #addReportingDirective(CSPDirective, String...)} with the sandbox
- * {@link CSPDirective} and a single empty string (<em>not</em> {@code null}) to add the empty
- * sandbox directive.
- */
- public CSPSettingRequestCycleListener addReportingDirective(CSPDirective sandboxDirective,
- CSPDirectiveSandboxValue... values)
- {
- for (CSPDirectiveSandboxValue value : values)
+ // @returns "key1 value1a value1b; key2 value2a; key3 value3a value3b value3c"
+ public String renderHeaderValue(RequestCycle cycle)
{
- addDirective(sandboxDirective, value, CSPHeaderMode.REPORT_ONLY);
+ return directives.entrySet()
+ .stream()
+ .map(e -> e.getKey().getValue() + " "
+ + e.getValue()
+ .stream()
+ .map(r -> r.render(CSPSettingRequestCycleListener.this, cycle))
+ .collect(Collectors.joining(" ")))
+ .collect(Collectors.joining("; "));
}
- return this;
}
- /**
- * Adds any value to a directive for the 'reporting-only' CSP header. Use
- * {@link #addReportingDirective(CSPDirective, CSPDirectiveSandboxValue...)} and
- * {@link #addReportingDirective(CSPDirective, CSPDirectiveSrcValue...)} for the default values
- * for the sandbox and -src directives.
- */
- public CSPSettingRequestCycleListener addReportingDirective(CSPDirective directive,
- String... values)
+ private Function<Integer, byte[]> randomSupplier;
+
+ private Map<CSPHeaderMode, CSPConfiguration> configs = new HashMap<>();
+
+ public CSPSettingRequestCycleListener()
{
- for (String value : values)
- {
- addDirective(directive, new FixedCSPDirective(value), CSPHeaderMode.REPORT_ONLY);
- }
- return this;
}
- private CSPSettingRequestCycleListener addDirective(CSPDirective directive, CSPRenderable value,
- CSPHeaderMode mode)
+ public CSPSettingRequestCycleListener(Function<Integer, byte[]> randomSupplier)
{
- // Add backwards compatible frame-src
- // see http://caniuse.com/#feat=contentsecuritypolicy2
- if (CSPDirective.CHILD_SRC.equals(directive))
- {
- addDirective(CSPDirective.FRAME_SRC, value, mode);
- }
- switch (mode)
- {
- case BLOCKING:
- if (blockingDirectives.get(directive) == null)
- {
- blockingDirectives.put(directive, new ArrayList<>());
- }
- directive.checkValueForDirective(value, blockingDirectives.get(directive));
- blockingDirectives.get(directive).add(value);
- return this;
- case REPORT_ONLY:
- if (reportingDirectives.get(directive) == null)
- {
- reportingDirectives.put(directive, new ArrayList<>());
- }
- directive.checkValueForDirective(value, reportingDirectives.get(directive));
- reportingDirectives.get(directive).add(value);
- return this;
- default:
- throw new IllegalArgumentException("Incorrect CSPHeaderMode!");
- }
+ this.randomSupplier = randomSupplier;
+ }
+
+ public CSPConfiguration blocking()
+ {
+ return configs.computeIfAbsent(CSPHeaderMode.BLOCKING, CSPConfiguration::new);
+ }
+ public CSPConfiguration reporting()
+ {
+ return configs.computeIfAbsent(CSPHeaderMode.REPORT_ONLY, CSPConfiguration::new);
}
@Override
public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler)
{
WebResponse webResponse = (WebResponse) cycle.getResponse();
- if (!reportingDirectives.isEmpty())
- {
- String reportHeaderValue = getCSPHeaderValue(reportingDirectives, cycle);
- webResponse.setHeader(HEADER_CSP_REPORT, reportHeaderValue);
- if (addLegacyHeaders)
- webResponse.setHeader(HEADER_CSP_REPORT_IE, reportHeaderValue);
- }
- if (!blockingDirectives.isEmpty())
- {
- String blockHeaderValue = getCSPHeaderValue(blockingDirectives, cycle);
- webResponse.setHeader(HEADER_CSP, blockHeaderValue);
- if (addLegacyHeaders)
- webResponse.setHeader(HEADER_CSP_IE, blockHeaderValue);
- }
+ configs.values().stream().filter(CSPConfiguration::isSet).forEach(config -> {
+ String headerValue = config.renderHeaderValue(cycle);
+ webResponse.setHeader(config.getMode().getHeader(), headerValue);
+ if (config.isAddLegacyHeaders())
+ webResponse.setHeader(config.getMode().getLegacyHeader(), headerValue);
+ });
}
public String getNonce(RequestCycle cycle)
@@ -518,18 +494,4 @@ public class CSPSettingRequestCycleListener implements IRequestCycleListener
}
return nonce;
}
-
- // @returns "key1 value1a value1b; key2 value2a; key3 value3a value3b value3c"
- private String getCSPHeaderValue(Map<CSPDirective, List<CSPRenderable>> directiveValuesMap,
- RequestCycle cycle)
- {
- return directiveValuesMap.entrySet()
- .stream()
- .map(e -> e.getKey().getValue() + " "
- + e.getValue()
- .stream()
- .map(r -> r.render(this, cycle))
- .collect(Collectors.joining(" ")))
- .collect(Collectors.joining("; "));
- }
}
diff --git a/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java b/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java
index 8e00759..f347f8a 100644
--- a/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/csp/CSPSettingRequestCycleListenerTest.java
@@ -50,7 +50,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, (String) null);
+ cspListener.blocking().addDirective(DEFAULT_SRC, (String) null);
});
}
@@ -59,7 +59,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, "");
+ cspListener.blocking().addDirective(DEFAULT_SRC, "");
});
}
@@ -72,7 +72,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, "abc?^()-_\'xyz");
+ cspListener.blocking().addDirective(DEFAULT_SRC, "abc?^()-_\'xyz");
});
}
@@ -85,7 +85,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, SELF, NONE);
+ cspListener.blocking().addDirective(DEFAULT_SRC, SELF, NONE);
});
}
@@ -98,7 +98,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, NONE, SELF);
+ cspListener.blocking().addDirective(DEFAULT_SRC, NONE, SELF);
});
}
@@ -110,9 +110,9 @@ public class CSPSettingRequestCycleListenerTest
public void testMultipleSrcInputWithStarIsRejected1()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(DEFAULT_SRC, SELF);
+ cspListener.blocking().addDirective(DEFAULT_SRC, SELF);
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, WILDCARD);
+ cspListener.blocking().addDirective(DEFAULT_SRC, WILDCARD);
});
}
@@ -124,9 +124,9 @@ public class CSPSettingRequestCycleListenerTest
public void testMultipleSrcInputWithStarIsRejected2()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(DEFAULT_SRC, WILDCARD);
+ cspListener.blocking().addDirective(DEFAULT_SRC, WILDCARD);
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, SELF);
+ cspListener.blocking().addDirective(DEFAULT_SRC, SELF);
});
}
@@ -135,7 +135,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(DEFAULT_SRC, ALLOW_FORMS);
+ cspListener.blocking().addDirective(DEFAULT_SRC, ALLOW_FORMS);
});
}
@@ -144,7 +144,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(SANDBOX, SELF);
+ cspListener.blocking().addDirective(SANDBOX, SELF);
});
}
@@ -153,7 +153,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(SANDBOX, (String) null);
+ cspListener.blocking().addDirective(SANDBOX, (String) null);
});
}
@@ -161,7 +161,7 @@ public class CSPSettingRequestCycleListenerTest
public void testEmptySandboxInputIsAccepted()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(SANDBOX, CSPDirectiveSandboxValue.EMPTY);
+ cspListener.blocking().addDirective(SANDBOX, CSPDirectiveSandboxValue.EMPTY);
}
@Test
@@ -169,7 +169,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(SANDBOX, "abcxyz");
+ cspListener.blocking().addDirective(SANDBOX, "abcxyz");
});
}
@@ -177,9 +177,9 @@ public class CSPSettingRequestCycleListenerTest
public void testMultipleSandboxInputWithEmptyStringIsRejected1()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(SANDBOX, ALLOW_FORMS);
+ cspListener.blocking().addDirective(SANDBOX, ALLOW_FORMS);
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(SANDBOX, EMPTY);
+ cspListener.blocking().addDirective(SANDBOX, EMPTY);
});
}
@@ -187,9 +187,9 @@ public class CSPSettingRequestCycleListenerTest
public void testMultipleSandboxInputWithEmptyStringIsRejected2()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(SANDBOX, EMPTY);
+ cspListener.blocking().addDirective(SANDBOX, EMPTY);
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(SANDBOX, ALLOW_FORMS);
+ cspListener.blocking().addDirective(SANDBOX, ALLOW_FORMS);
});
}
@@ -198,7 +198,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(REPORT_URI, (String) null);
+ cspListener.blocking().addDirective(REPORT_URI, (String) null);
});
}
@@ -207,7 +207,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(REPORT_URI, "");
+ cspListener.blocking().addDirective(REPORT_URI, "");
});
}
@@ -216,7 +216,7 @@ public class CSPSettingRequestCycleListenerTest
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
- cspListener.addBlockingDirective(REPORT_URI, "abc?^()-_\'xyz");
+ cspListener.blocking().addDirective(REPORT_URI, "abc?^()-_\'xyz");
});
}
@@ -240,9 +240,9 @@ public class CSPSettingRequestCycleListenerTest
{
final CSPDirectiveSrcValue cspDirectiveValue =
CSPDirectiveSrcValue.values()[i % cspDirectiveSrcValueCount];
- cspListener.addBlockingDirective(cspDirective, cspDirectiveValue);
+ cspListener.blocking().addDirective(cspDirective, cspDirectiveValue);
- cspListener.addReportingDirective(cspDirective, cspDirectiveValue);
+ cspListener.reporting().addDirective(cspDirective, cspDirectiveValue);
}
}
@@ -258,8 +258,8 @@ public class CSPSettingRequestCycleListenerTest
public void testCSPReportUriDirectiveSetCorrectly()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(REPORT_URI, "http://report.example.com");
- cspListener.addReportingDirective(REPORT_URI, "/example-report-uri");
+ cspListener.blocking().addDirective(REPORT_URI, "http://report.example.com");
+ cspListener.reporting().addDirective(REPORT_URI, "/example-report-uri");
StringBuffer headerErrors = checkHeaders(cspListener);
@@ -280,8 +280,8 @@ public class CSPSettingRequestCycleListenerTest
if (cspDirectiveValue.equals(CSPDirectiveSandboxValue.EMPTY))
continue;
- cspListener.addBlockingDirective(SANDBOX, cspDirectiveValue);
- cspListener.addReportingDirective(SANDBOX, cspDirectiveValue);
+ cspListener.blocking().addDirective(SANDBOX, cspDirectiveValue);
+ cspListener.reporting().addDirective(SANDBOX, cspDirectiveValue);
}
StringBuffer headerErrors = checkHeaders(cspListener);
@@ -301,8 +301,8 @@ public class CSPSettingRequestCycleListenerTest
public void testChildSrcDirectiveAlsoSetsFrameSrcDirective()
{
CSPSettingRequestCycleListener cspListener = new CSPSettingRequestCycleListener();
- cspListener.addBlockingDirective(CHILD_SRC, SELF);
- cspListener.addReportingDirective(CHILD_SRC, SELF);
+ cspListener.blocking().addDirective(CHILD_SRC, SELF);
+ cspListener.reporting().addDirective(CHILD_SRC, SELF);
StringBuffer headerErrors = checkHeaders(cspListener);
if (headerErrors.length() > 0)