CVE-2017-16763: Insufficient Information (NVD-CWE-noinfo)
value: An exploitable vulnerability exists in the YAML parsing functionality in config.py in Confire 0.2.0. Due to the user-specific configuration being loaded from "~/.confire.yaml" using the yaml.load function, a YAML parser can execute arbitrary Python commands resulting in command execution. An attacker can insert Python into loaded YAML to trigger this vulnerability.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 9.8
Published: 2017-11-10T09:29Z
Repository: https://github.com/bbengfort/confire
Language: Python
Files changed: confire/config.py, tests/test_conf.py, tests/test_descriptors.py, tests/test_environ.py, tests/test_paths.py, tests/test_safety.py
Commit date: 2017-11-11 10:20:25 -0500
Commit message: use safe load instead of load

Diff: diff --git a/confire/config.py b/confire/config.py
index ac7a86b..5403fb2 100644
--- a/confire/config.py
+++ b/confire/config.py
@@ -141,11 +141,11 @@ class Configuration(with_metaclass(SettingsMeta, object)):
         """
         config = klass()
         for path in klass.CONF_PATHS:
             if os.path.exists(path):
                 with open(path, 'r') as conf:
-                    config.configure(yaml.load(conf))
+                    config.configure(yaml.safe_load(conf))
         return config
 
     def configure(self, conf={}):
         """
         Allows updating of the configuration via a dictionary of
diff --git a/tests/test_conf.py b/tests/test_conf.py
index 7675afb..c0aadf5 100644
--- a/tests/test_conf.py
+++ b/tests/test_conf.py
@@ -1,15 +1,15 @@
-# tests.conf_tests
+# tests.test_conf
 # Testing the configuration module for Confire
 #
 # Author:   Benjamin Bengfort <benjamin@bengfort.com>
 # Created:  Sun Jul 20 09:43:33 2014 -0400
 #
 # Copyright (C) 2014 Bengfort.com
 # For license information, see LICENSE.txt
 #
-# ID: conf_tests.py [] benjamin@bengfort.com $
+# ID: test_conf.py [] benjamin@bengfort.com $
 
 """
 Testing the configuration module for Confire
 
 TODO: Write test for None values in config
diff --git a/tests/test_descriptors.py b/tests/test_descriptors.py
index 14373f6..ea7db1a 100644
--- a/tests/test_descriptors.py
+++ b/tests/test_descriptors.py
@@ -1,15 +1,15 @@
-# tests.descriptors_tests
+# tests.test_descriptors
 # Implements a base SettingsDescriptor for advanced configurations
 #
 # Author:   Benjamin Bengfort <benjamin@bengfort.com>
 # Created:  Thu Jun 11 09:34:33 2015 -0400
 #
 # Copyright (C) 2015 Bengfort.com
 # For license information, see LICENSE.txt
 #
-# ID: descriptors_tests.py [] benjamin@bengfort.com $
+# ID: test_descriptors.py [] benjamin@bengfort.com $
 
 """
 Implements a base SettingsDescriptor for advanced configurations
 """
 
diff --git a/tests/test_environ.py b/tests/test_environ.py
index 31a52f2..d91762e 100644
--- a/tests/test_environ.py
+++ b/tests/test_environ.py
@@ -1,15 +1,15 @@
-# tests.environ_tests
+# tests.test_environ
 # Tests the environment configuration ability
 #
 # Author:   Benjamin Bengfort <benjamin@bengfort.com>
 # Created:  Mon Jul 21 11:17:23 2014 -0400
 #
 # Copyright (C) 2014 Bengfort.com
 # For license information, see LICENSE.txt
 #
-# ID: environ_tests.py [] benjamin@bengfort.com $
+# ID: test_environ.py [] benjamin@bengfort.com $
 
 """
 Tests the environment configuration ability
 """
 
diff --git a/tests/test_paths.py b/tests/test_paths.py
index d27999f..a0f5da4 100644
--- a/tests/test_paths.py
+++ b/tests/test_paths.py
@@ -1,15 +1,15 @@
-# tests.paths_tests
+# tests.test_paths
 # Testing the paths descriptor
 #
 # Author:   Benjamin Bengfort <benjamin@bengfort.com>
 # Created:  Thu Jun 11 08:09:40 2015 -0400
 #
 # Copyright (C) 2014 Bengfort.com
 # For license information, see LICENSE.txt
 #
-# ID: paths_tests.py [] benjamin@bengfort.com $
+# ID: test_paths.py [] benjamin@bengfort.com $
 
 """
 Testing the paths descriptor
 """
 
diff --git a/tests/test_safety.py b/tests/test_safety.py
new file mode 100644
index 0000000..05d10a4
--- /dev/null
+++ b/tests/test_safety.py
@@ -0,0 +1,40 @@
+# tests.test_safety
+# Test that we're using safe methods
+#
+# Author:   Benjamin Bengfort <benjamin@bengfort.com>
+# Created:  Fri Nov 10 12:22:35 2017 -0500
+#
+# Copyright (C) 2014 Bengfort.com
+# For license information, see LICENSE.txt
+#
+# ID: test_safety.py [] benjamin@bengfort.com $
+
+"""
+Testing the paths descriptor
+"""
+
+##########################################################################
+## Imports
+##########################################################################
+
+import os
+
+from unittest import mock
+
+
+# Cannot import from test_conf.py to ensure correct mock
+TESTDATA = os.path.join(os.path.dirname(__file__), "testdata")
+TESTCONF = os.path.join(TESTDATA, "testconf.yaml")
+
+
+@mock.patch('confire.config.yaml')
+def test_use_yaml_safe_load(mock_yaml):
+    """
+    Ensure we're using yaml.safe_load not yaml.load
+    """
+    from confire.config import Configuration
+    Configuration.CONF_PATHS = [TESTCONF]
+    Configuration.load()
+
+    mock_yaml.safe_load.assert_called_once()
+    mock_yaml.load.assert_not_called()

Vulnerable code:                     config.configure(yaml.load(conf))
# tests.conf_tests
# ID: conf_tests.py [] benjamin@bengfort.com $
# tests.descriptors_tests
# ID: descriptors_tests.py [] benjamin@bengfort.com $
# tests.environ_tests
# ID: environ_tests.py [] benjamin@bengfort.com $
# tests.paths_tests
# ID: paths_tests.py [] benjamin@bengfort.com $
Fixed code:                     config.configure(yaml.safe_load(conf))
# tests.test_conf
# ID: test_conf.py [] benjamin@bengfort.com $
# tests.test_descriptors
# ID: test_descriptors.py [] benjamin@bengfort.com $
# tests.test_environ
# ID: test_environ.py [] benjamin@bengfort.com $
# tests.test_paths
# ID: test_paths.py [] benjamin@bengfort.com $
# tests.test_safety
# Test that we're using safe methods
#
# Author:   Benjamin Bengfort <benjamin@bengfort.com>
# Created:  Fri Nov 10 12:22:35 2017 -0500
#
# Copyright (C) 2014 Bengfort.com
# For license information, see LICENSE.txt
#
# ID: test_safety.py [] benjamin@bengfort.com $

"""
Testing the paths descriptor
"""

##########################################################################
## Imports
##########################################################################

import os

from unittest import mock


# Cannot import from test_conf.py to ensure correct mock
TESTDATA = os.path.join(os.path.dirname(__file__), "testdata")
TESTCONF = os.path.join(TESTDATA, "testconf.yaml")


@mock.patch('confire.config.yaml')
def test_use_yaml_safe_load(mock_yaml):
    """
    Ensure we're using yaml.safe_load not yaml.load
    """
    from confire.config import Configuration
    Configuration.CONF_PATHS = [TESTCONF]
    Configuration.load()

    mock_yaml.safe_load.assert_called_once()
    mock_yaml.load.assert_not_called()