CVE-2014-1691: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: The framework/Util/lib/Horde/Variables.php script in the Util library in Horde before 5.1.1 allows remote attackers to conduct object injection attacks and execute arbitrary PHP code via a crafted serialized object in the _formvars form.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
Published: 2014-04-01T15:55Z
Repository: https://github.com/horde/horde
Language: PHP
Files changed: framework/Util/lib/Horde/Variables.php, framework/Util/package.xml
Commit date: 2013-06-27 09:25:43 -0600
Commit message: [mms] SECURITY: '_formvars' form input must now be JSON encoded, not PHP serialized.

Diff: diff --git a/framework/Util/lib/Horde/Variables.php b/framework/Util/lib/Horde/Variables.php
index f9e77ebca1..1de39e6107 100644
--- a/framework/Util/lib/Horde/Variables.php
+++ b/framework/Util/lib/Horde/Variables.php
@@ -59,22 +59,24 @@ class Horde_Variables implements ArrayAccess, Countable, IteratorAggregate
 
     /**
      * Constructor.
      *
      * @param array $vars       The list of form variables (if null, defaults
-     *                          to PHP's $_REQUEST value).
+     *                          to PHP's $_REQUEST value). If '_formvars'
+     *                          exists, it must be a JSON encoded array that
+     *                          contains the list of allowed form variables.
      * @param string $sanitize  Sanitize the input variables?
      */
     public function __construct($vars = array(), $sanitize = false)
     {
         if (is_null($vars)) {
             $request_copy = $_REQUEST;
             $vars = Horde_Util::dispelMagicQuotes($request_copy);
         }
 
         if (isset($vars['_formvars'])) {
-            $this->_expected = @unserialize($vars['_formvars']);
+            $this->_expected = @json_decode($vars['_formvars'], true);
             unset($vars['_formvars']);
         }
 
         $this->_vars = $vars;
 
diff --git a/framework/Util/package.xml b/framework/Util/package.xml
index c9be1069dd..2a3df6c7b6 100644
--- a/framework/Util/package.xml
+++ b/framework/Util/package.xml
@@ -24,20 +24,20 @@
   <active>yes</active>
  </developer>
  <date>2013-05-06</date>
  <time>19:34:35</time>
  <version>
-  <release>2.2.3</release>
-  <api>2.2.0</api>
+  <release>2.3.0</release>
+  <api>2.3.0</api>
  </version>
  <stability>
   <release>stable</release>
   <api>stable</api>
  </stability>
  <license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
  <notes>
-* 
+* [mms] SECURITY: &apos;_formvars&apos; form input must now be JSON encoded, not PHP serialized.
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
    <dir name="doc">
     <dir name="Horde">
@@ -114,10 +114,13 @@
     <name>filter</name>
    </extension>
    <extension>
     <name>iconv</name>
    </extension>
+   <extension>
+    <name>json</name>
+   </extension>
    <extension>
     <name>mbstring</name>
    </extension>
    <extension>
     <name>xml</name>
@@ -617,18 +620,18 @@ Converted to package.xml 2.0 for pear.horde.org
 * [mms] Fix Horde_Domhtml#returnBody().
    </notes>
   </release>
   <release>
    <version>
-    <release>2.2.3</release>
-    <api>2.2.0</api></version>
+    <release>2.3.0</release>
+    <api>2.3.0</api></version>
    <stability>
     <release>stable</release>
     <api>stable</api></stability>
    <date>2013-05-06</date>
    <license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
    <notes>
-* 
+* [mms] SECURITY: &apos;_formvars&apos; form input must now be JSON encoded, not PHP serialized.
    </notes>
   </release>
  </changelog>
 </package>

Vulnerable code:      *                          to PHP's $_REQUEST value).
            $this->_expected = @unserialize($vars['_formvars']);
  <release>2.2.3</release>
  <api>2.2.0</api>
* 
    <release>2.2.3</release>
    <api>2.2.0</api></version>
* 
Fixed code:      *                          to PHP's $_REQUEST value). If '_formvars'
     *                          exists, it must be a JSON encoded array that
     *                          contains the list of allowed form variables.
            $this->_expected = @json_decode($vars['_formvars'], true);
  <release>2.3.0</release>
  <api>2.3.0</api>
* [mms] SECURITY: &apos;_formvars&apos; form input must now be JSON encoded, not PHP serialized.
   <extension>
    <name>json</name>
   </extension>
    <release>2.3.0</release>
    <api>2.3.0</api></version>
* [mms] SECURITY: &apos;_formvars&apos; form input must now be JSON encoded, not PHP serialized.