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

oheger pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-configuration.git


The following commit(s) were added to refs/heads/master by this push:
     new add7375  Prevent object creation when loading YAML files.
add7375 is described below

commit add7375cf37fd316d4838c6c56b054fc293b4641
Author: oheger <oliver.he...@oliver-heger.de>
AuthorDate: Wed Mar 4 21:33:22 2020 +0100

    Prevent object creation when loading YAML files.
    
    When creating a new Yaml instance from SnakeYaml to read in a
    configuration file the instance is now configured that no objects are
    created automatically.
---
 .../commons/configuration2/YAMLConfiguration.java  | 41 +++++++++++++++--
 .../configuration2/TestYAMLConfiguration.java      | 53 ++++++++++++++++++++--
 2 files changed, 87 insertions(+), 7 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/configuration2/YAMLConfiguration.java 
b/src/main/java/org/apache/commons/configuration2/YAMLConfiguration.java
index 1593d12..2b15d66 100644
--- a/src/main/java/org/apache/commons/configuration2/YAMLConfiguration.java
+++ b/src/main/java/org/apache/commons/configuration2/YAMLConfiguration.java
@@ -18,11 +18,14 @@
 package org.apache.commons.configuration2;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.commons.configuration2.ex.ConfigurationRuntimeException;
 import org.apache.commons.configuration2.io.InputStreamSupport;
 import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.LoaderOptions;
 import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.representer.Representer;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -65,7 +68,7 @@ public class YAMLConfiguration extends 
AbstractYAMLBasedConfiguration
     {
         try
         {
-            final Yaml yaml = new Yaml();
+            final Yaml yaml = createYamlForReading(new LoaderOptions());
             final Map<String, Object> map = (Map) yaml.load(in);
             load(map);
         }
@@ -80,7 +83,7 @@ public class YAMLConfiguration extends 
AbstractYAMLBasedConfiguration
     {
         try
         {
-            final Yaml yaml = new Yaml(options);
+            final Yaml yaml = createYamlForReading(options);
             final Map<String, Object> map = (Map) yaml.load(in);
             load(map);
         }
@@ -117,7 +120,7 @@ public class YAMLConfiguration extends 
AbstractYAMLBasedConfiguration
     {
         try
         {
-            final Yaml yaml = new Yaml();
+            final Yaml yaml = createYamlForReading(new LoaderOptions());
             final Map<String, Object> map = (Map) yaml.load(in);
             load(map);
         }
@@ -132,7 +135,7 @@ public class YAMLConfiguration extends 
AbstractYAMLBasedConfiguration
     {
         try
         {
-            final Yaml yaml = new Yaml(options);
+            final Yaml yaml = createYamlForReading(options);
             final Map<String, Object> map = (Map) yaml.load(in);
             load(map);
         }
@@ -142,4 +145,34 @@ public class YAMLConfiguration extends 
AbstractYAMLBasedConfiguration
         }
     }
 
+    /**
+     * Creates a {@code Yaml} object for reading a Yaml file. The object is
+     * configured with some default settings.
+     *
+     * @param options options for loading the file
+     * @return the {@code Yaml} instance for loading a file
+     */
+    private static Yaml createYamlForReading(LoaderOptions options)
+    {
+        return new Yaml(createClassLoadingDisablingConstructor(), new 
Representer(), new DumperOptions(), options);
+    }
+
+    /**
+     * Returns a {@code Constructor} object for the YAML parser that prevents
+     * all classes from being loaded. This effectively disables the dynamic
+     * creation of Java objects that are declared in YAML files to be loaded.
+     *
+     * @return the {@code Constructor} preventing object creation
+     */
+    private static Constructor createClassLoadingDisablingConstructor()
+    {
+        return new Constructor()
+        {
+            @Override
+            protected Class<?> getClassForName(String name)
+            {
+                throw new ConfigurationRuntimeException("Class loading is 
disabled.");
+            }
+        };
+    }
 }
diff --git 
a/src/test/java/org/apache/commons/configuration2/TestYAMLConfiguration.java 
b/src/test/java/org/apache/commons/configuration2/TestYAMLConfiguration.java
index dbdaea0..0945a30 100644
--- a/src/test/java/org/apache/commons/configuration2/TestYAMLConfiguration.java
+++ b/src/test/java/org/apache/commons/configuration2/TestYAMLConfiguration.java
@@ -17,26 +17,37 @@
 
 package org.apache.commons.configuration2;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
+import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.StringReader;
 import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.yaml.snakeyaml.Yaml;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 /**
  * Unit test for {@link YAMLConfiguration}
  */
 public class TestYAMLConfiguration
 {
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
     /** The files that we test with. */
     private final String testYaml =
             ConfigurationAssert.getTestFile("test.yaml").getAbsolutePath();
@@ -134,4 +145,40 @@ public class TestYAMLConfiguration
         yamlConfiguration = new YAMLConfiguration(c);
         assertEquals("bar", yamlConfiguration.getString("foo"));
     }
+
+    @Test
+    public void testObjectCreationFromReader()
+    {
+        final File createdFile = new File(temporaryFolder.getRoot(), 
"data.txt");
+        final String yaml = "!!java.io.FileOutputStream [" + 
createdFile.getAbsolutePath() + "]";
+
+        try
+        {
+            yamlConfiguration.read(new StringReader(yaml));
+            fail("Loading configuration did not cause an exception!");
+        }
+        catch (ConfigurationException e)
+        {
+            //expected
+        }
+        assertFalse("Java object was created", createdFile.exists());
+    }
+
+    @Test
+    public void testObjectCreationFromStream()
+    {
+        final File createdFile = new File(temporaryFolder.getRoot(), 
"data.txt");
+        final String yaml = "!!java.io.FileOutputStream [" + 
createdFile.getAbsolutePath() + "]";
+
+        try
+        {
+            yamlConfiguration.read(new 
ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)));
+            fail("Loading configuration did not cause an exception!");
+        }
+        catch (ConfigurationException e)
+        {
+            //expected
+        }
+        assertFalse("Java object was created", createdFile.exists());
+    }
 }

Reply via email to