diff --git a/wicket-core/src/main/java/org/apache/wicket/csp/CSPDirective.java b/wicket-core/src/main/java/org/apache/wicket/csp/CSPDirective.java index 235358a02f6..6f840ab5ff1 100644 --- a/wicket-core/src/main/java/org/apache/wicket/csp/CSPDirective.java +++ b/wicket-core/src/main/java/org/apache/wicket/csp/CSPDirective.java @@ -35,7 +35,11 @@ public enum CSPDirective { DEFAULT_SRC("default-src"), SCRIPT_SRC("script-src"), + SCRIPT_SRC_ATTR("script-src-attr"), + SCRIPT_SRC_ELEM("script-src-elem"), STYLE_SRC("style-src"), + STYLE_SRC_ATTR("style-src-attr"), + STYLE_SRC_ELEM("style-src-elem"), IMG_SRC("img-src"), CONNECT_SRC("connect-src"), FONT_SRC("font-src"), @@ -121,7 +125,7 @@ public void checkValueForDirective(CSPRenderable value, } }; - private String value; + private final String value; CSPDirective(String value) { @@ -135,7 +139,7 @@ public String getValue() /** * Check if {@code value} can be added to the list of other values. By default, it checks for - * conflicts with wildcards and none and it checks if values are valid uris. + * conflicts with wildcards and none, and it checks if values are valid uris. * * @param value * The value to add. @@ -147,6 +151,19 @@ public String getValue() public void checkValueForDirective(CSPRenderable value, List existingDirectiveValues) { + if (this == SCRIPT_SRC_ATTR || this == STYLE_SRC_ATTR) + { + if (!existingDirectiveValues.isEmpty()) + { + throw new IllegalArgumentException("Directive " + this + " supports only one value"); + } + + if (!CSPDirectiveSrcValue.NONE.equals(value) && !CSPDirectiveSrcValue.UNSAFE_INLINE.equals(value)) + { + throw new IllegalArgumentException("Unsupported directive value: " + value + " for -src-attr directive"); + } + } + if (!existingDirectiveValues.isEmpty()) { if (CSPDirectiveSrcValue.WILDCARD.equals(value) @@ -185,11 +202,11 @@ public static CSPDirective fromValue(String value) { return null; } - for (int i = 0; i < values().length; i++) + for (CSPDirective directive : values()) { - if (value.equals(values()[i].getValue())) + if (value.equals(directive.getValue())) { - return values()[i]; + return directive; } } return null; diff --git a/wicket-core/src/test/java/org/apache/wicket/csp/CSPDirectiveTest.java b/wicket-core/src/test/java/org/apache/wicket/csp/CSPDirectiveTest.java new file mode 100644 index 00000000000..1d13dace910 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/csp/CSPDirectiveTest.java @@ -0,0 +1,58 @@ +/* + * 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.csp; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class CSPDirectiveTest { + + @Test + void scriptSrcAttrAndStyleSrcAttributesSupportValues() + { + CSPDirective.SCRIPT_SRC_ATTR.checkValueForDirective(CSPDirectiveSrcValue.NONE, List.of()); + CSPDirective.SCRIPT_SRC_ATTR.checkValueForDirective(CSPDirectiveSrcValue.UNSAFE_INLINE, List.of()); + CSPDirective.STYLE_SRC_ATTR.checkValueForDirective(CSPDirectiveSrcValue.NONE, List.of()); + CSPDirective.STYLE_SRC_ATTR.checkValueForDirective(CSPDirectiveSrcValue.UNSAFE_INLINE, List.of()); + } + + @Test + void scriptSrcAttrAndStyleSrcAttributesOnlySupportOneValue() + { + assertThrows(IllegalArgumentException.class, () -> + CSPDirective.SCRIPT_SRC_ATTR.checkValueForDirective(CSPDirectiveSrcValue.NONE, List.of(CSPDirectiveSrcValue.UNSAFE_INLINE))); + assertThrows(IllegalArgumentException.class, () -> + CSPDirective.STYLE_SRC_ATTR.checkValueForDirective(CSPDirectiveSrcValue.UNSAFE_INLINE, List.of(CSPDirectiveSrcValue.UNSAFE_INLINE))); + } + + @Test + void scriptSrcAttrAndStyleSrcAttributesOnlySupportNoneAndUnsafeInline() + { + for (CSPDirectiveSrcValue value : CSPDirectiveSrcValue.values()) { + if (value == CSPDirectiveSrcValue.NONE || value == CSPDirectiveSrcValue.UNSAFE_INLINE) { + CSPDirective.SCRIPT_SRC_ATTR.checkValueForDirective(value, List.of()); + CSPDirective.STYLE_SRC_ATTR.checkValueForDirective(value, List.of()); + } else { + assertThrows(IllegalArgumentException.class, () -> CSPDirective.SCRIPT_SRC_ATTR.checkValueForDirective(value, List.of())); + } + } + } + +}