diff --git a/swatch-product-configuration/src/main/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistry.java b/swatch-product-configuration/src/main/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistry.java index 4de30e69df..1bc810d52c 100644 --- a/swatch-product-configuration/src/main/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistry.java +++ b/swatch-product-configuration/src/main/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistry.java @@ -30,6 +30,9 @@ import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; +import org.yaml.snakeyaml.inspector.TagInspector; +import org.yaml.snakeyaml.inspector.UnTrustedTagInspector; +import org.yaml.snakeyaml.nodes.Tag; /** * Loads yaml files from src/main/resource/subscription_configs into List. Provides @@ -59,8 +62,11 @@ public static synchronized void reset() { SubscriptionDefinitionRegistry() { subscriptions = new ArrayList<>(); + var options = new LoaderOptions(); + options.setTagInspector(new UnTrustedTagInspector()); options.setEnumCaseSensitive(false); + Constructor constructor = new Constructor(SubscriptionDefinition.class, options); constructor.getPropertyUtils().setSkipMissingProperties(true); diff --git a/swatch-product-configuration/src/test/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistryTest.java b/swatch-product-configuration/src/test/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistryTest.java index 4f722e8e0f..946ef208c9 100644 --- a/swatch-product-configuration/src/test/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistryTest.java +++ b/swatch-product-configuration/src/test/java/com/redhat/swatch/configuration/registry/SubscriptionDefinitionRegistryTest.java @@ -28,6 +28,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.yaml.snakeyaml.composer.ComposerException; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; @TestInstance(Lifecycle.PER_CLASS) class SubscriptionDefinitionRegistryTest { @@ -36,6 +42,19 @@ class SubscriptionDefinitionRegistryTest { @BeforeAll void setup() { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + var url = classLoader.getResource("swatch_config_index.txt"); + + if (Files.isSymbolicLink(Paths.get(url.getPath()))){ + var warning = """ + Detected a symlink version of swatch_config_index.txt. This link should only be used + in testNoGlobalTags(). Its presence indicates a failure of the test to clean up after itself. + Please delete the symlink at %s and rerun the tests. + Also consider investigating why the symlink was not deleted after completion of the test. + """.formatted(url.getPath()); + throw new IllegalStateException(warning); + } + subscriptionDefinitionRegistry = new SubscriptionDefinitionRegistry(); } @@ -52,6 +71,34 @@ void testValidations() { } } + @Test + /** Test for SnakeYaml deserialization vulnerability due to enabled global tags. See + * + */ + void testNoGlobalTags() throws IOException { + Path link = null; + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + var url = classLoader.getResource("cve_2022_1471_swatch_config_index.txt"); + Path target = Paths.get(url.getPath()); + Path parent = target.getParent(); + + link = parent.resolve("swatch_config_index.txt"); + Files.createSymbolicLink(link, target); + assertThrows(ComposerException.class, SubscriptionDefinitionRegistry::new); + } finally { + if (link != null && Files.exists(link)) { + Files.delete(link); + } + } + + } + @Test void testLoadAllTheThings() { assertFalse(subscriptionDefinitionRegistry.getSubscriptions().isEmpty()); diff --git a/swatch-product-configuration/src/test/resources/cve_2022_1471_product.yaml b/swatch-product-configuration/src/test/resources/cve_2022_1471_product.yaml new file mode 100644 index 0000000000..f05eb21e3d --- /dev/null +++ b/swatch-product-configuration/src/test/resources/cve_2022_1471_product.yaml @@ -0,0 +1,2 @@ +# From https://snyk.io/blog/unsafe-deserialization-snakeyaml-java-cve-2022-1471/ +!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://localhost:8080/"]]]] diff --git a/swatch-product-configuration/src/test/resources/cve_2022_1471_swatch_config_index.txt b/swatch-product-configuration/src/test/resources/cve_2022_1471_swatch_config_index.txt new file mode 100644 index 0000000000..17758527f8 --- /dev/null +++ b/swatch-product-configuration/src/test/resources/cve_2022_1471_swatch_config_index.txt @@ -0,0 +1 @@ +cve_2022_1471_product.yaml