High severityNVD Advisory· Published Jun 2, 2014· Updated May 6, 2026
CVE-2013-1397
CVE-2013-1397
Description
Symfony 2.0.x before 2.0.22, 2.1.x before 2.1.7, and 2.2.x remote attackers to execute arbitrary PHP code via a serialized PHP object to the (1) Yaml::parse or (2) Yaml\Parser::parse function, a different vulnerability than CVE-2013-1348.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
symfony/symfonyPackagist | >= 2.2.0-BETA1, < 2.2.0-BETA2 | 2.2.0-BETA2 |
symfony/symfonyPackagist | >= 2.0.0, < 2.0.22 | 2.0.22 |
symfony/symfonyPackagist | >= 2.1.0, < 2.1.7 | 2.1.7 |
symfony/yamlPackagist | >= 2.0.0, < 2.0.22 | 2.0.22 |
symfony/yamlPackagist | >= 2.1.0, < 2.1.7 | 2.1.7 |
symfony/yamlPackagist | >= 2.2.0-BETA1, < 2.2.0-BETA2 | 2.2.0-BETA2 |
Affected products
40cpe:2.3:a:sensiolabs:symfony:2.0.0:*:*:*:*:*:*:*+ 39 more
- cpe:2.3:a:sensiolabs:symfony:2.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.10:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.11:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.12:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.13:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.14:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.15:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.16:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.17:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.18:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.19:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.20:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.21:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.3:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.5:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.6:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.7:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.8:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.0.9:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.2:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.3:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.4:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.5:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.1.6:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.1:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.10:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.11:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.2:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.3:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.4:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.5:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.6:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.8:*:*:*:*:*:*:*
- cpe:2.3:a:sensiolabs:symfony:2.2.9:*:*:*:*:*:*:*
Patches
1ba6e3159c0eeadded a way to enable/disable object support when parsing/dumping
7 files changed · +122 −51
src/Symfony/Bridge/Twig/Extension/YamlExtension.php+5 −5 modified@@ -31,28 +31,28 @@ public function getFilters() ); } - public function encode($input, $inline = 0) + public function encode($input, $inline = 0, $dumpObjects = false) { static $dumper; if (null === $dumper) { $dumper = new YamlDumper(); } - return $dumper->dump($input, $inline); + return $dumper->dump($input, $inline, false, $dumpObjects); } - public function dump($value) + public function dump($value, $inline = 0, $dumpObjects = false) { if (is_resource($value)) { return '%Resource%'; } if (is_array($value) || is_object($value)) { - return '%'.gettype($value).'% '.$this->encode($value); + return '%'.gettype($value).'% '.$this->encode($value, $inline, $dumpObjects); } - return $this->encode($value); + return $this->encode($value, $inline, $dumpObjects); } /**
src/Symfony/Component/Yaml/Dumper.php+9 −7 modified@@ -21,19 +21,21 @@ class Dumper /** * Dumps a PHP value to YAML. * - * @param mixed $input The PHP value - * @param integer $inline The level where you switch to inline YAML - * @param integer $indent The level of indentation (used internally) + * @param mixed $input The PHP value + * @param integer $inline The level where you switch to inline YAML + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise + * @param integer $indent The level of indentation (used internally) * * @return string The YAML representation of the PHP value */ - public function dump($input, $inline = 0, $indent = 0) + public function dump($input, $inline = 0, $exceptionOnInvalidType = false, $objectSupport = false, $indent = 0) { $output = ''; $prefix = $indent ? str_repeat(' ', $indent) : ''; if ($inline <= 0 || !is_array($input) || empty($input)) { - $output .= $prefix.Inline::dump($input); + $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport); } else { $isAHash = array_keys($input) !== range(0, count($input) - 1); @@ -42,9 +44,9 @@ public function dump($input, $inline = 0, $indent = 0) $output .= sprintf('%s%s%s%s', $prefix, - $isAHash ? Inline::dump($key).':' : '-', + $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-', $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 2) + $this->dump($value, $inline - 1, $exceptionOnInvalidType, $objectSupport, $willBeInlined ? 0 : $indent + 2) ).($willBeInlined ? "\n" : ''); } }
src/Symfony/Component/Yaml/Inline.php+44 −12 modified@@ -22,15 +22,23 @@ class Inline { const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; + private static $exceptionOnInvalidType = false; + private static $objectSupport = false; + /** * Converts a YAML string to a PHP array. * - * @param string $value A YAML string + * @param string $value A YAML string + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return array A PHP array representing the YAML string */ - public static function parse($value) + public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false) { + self::$exceptionOnInvalidType = $exceptionOnInvalidType; + self::$objectSupport = $objectSupport; + $value = trim($value); if (0 == strlen($value)) { @@ -63,21 +71,35 @@ public static function parse($value) /** * Dumps a given PHP variable to a YAML string. * - * @param mixed $value The PHP variable to convert + * @param mixed $value The PHP variable to convert + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string The YAML string representing the PHP array * * @throws DumpException When trying to dump PHP resource */ - public static function dump($value) + public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false) { switch (true) { case is_resource($value): - throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); + if ($exceptionOnInvalidType) { + throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); + } + + return 'null'; case is_object($value): - return '!!php/object:'.serialize($value); + if ($objectSupport) { + return '!!php/object:'.serialize($value); + } + + if ($exceptionOnInvalidType) { + throw new DumpException('Object support when dumping a YAML file has been disabled.'); + } + + return 'null'; case is_array($value): - return self::dumpArray($value); + return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport); case null === $value: return 'null'; case true === $value: @@ -115,11 +137,13 @@ public static function dump($value) /** * Dumps a PHP array to a YAML string. * - * @param array $value The PHP array to dump + * @param array $value The PHP array to dump + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string The YAML string representing the PHP array */ - private static function dumpArray($value) + private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport) { // array $keys = array_keys($value); @@ -128,7 +152,7 @@ private static function dumpArray($value) ) { $output = array(); foreach ($value as $val) { - $output[] = self::dump($val); + $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport); } return sprintf('[%s]', implode(', ', $output)); @@ -137,7 +161,7 @@ private static function dumpArray($value) // mapping $output = array(); foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key), self::dump($val)); + $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport)); } return sprintf('{ %s }', implode(', ', $output)); @@ -355,7 +379,15 @@ private static function evaluateScalar($scalar) case 0 === strpos($scalar, '! '): return intval(self::parseScalar(substr($scalar, 2))); case 0 === strpos($scalar, '!!php/object:'): - return unserialize(substr($scalar, 13)); + if (self::$objectSupport) { + return unserialize(substr($scalar, 13)); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.'); + } + + return null; case ctype_digit($scalar): $raw = $scalar; $cast = intval($scalar);
src/Symfony/Component/Yaml/Parser.php+15 −11 modified@@ -38,13 +38,15 @@ public function __construct($offset = 0) /** * Parses a YAML string to a PHP value. * - * @param string $value A YAML string + * @param string $value A YAML string + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return mixed A PHP value * * @throws ParseException If the YAML is not valid */ - public function parse($value) + public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false) { $this->currentLineNb = -1; $this->currentLine = ''; @@ -82,7 +84,7 @@ public function parse($value) $c = $this->getRealCurrentLineNb() + 1; $parser = new Parser($c); $parser->refs =& $this->refs; - $data[] = $parser->parse($this->getNextEmbedBlock()); + $data[] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); } else { if (isset($values['leadspaces']) && ' ' == $values['leadspaces'] @@ -98,12 +100,14 @@ public function parse($value) $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2); } - $data[] = $parser->parse($block); + $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport); } else { - $data[] = $this->parseValue($values['value']); + $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport); } } } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) { + // force correct settings + Inline::parse(null, $exceptionOnInvalidType, $objectSupport); try { $key = Inline::parseScalar($values['key']); } catch (ParseException $e) { @@ -128,7 +132,7 @@ public function parse($value) $c = $this->getRealCurrentLineNb() + 1; $parser = new Parser($c); $parser->refs =& $this->refs; - $parsed = $parser->parse($value); + $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport); $merged = array(); if (!is_array($parsed)) { @@ -165,20 +169,20 @@ public function parse($value) $c = $this->getRealCurrentLineNb() + 1; $parser = new Parser($c); $parser->refs =& $this->refs; - $data[$key] = $parser->parse($this->getNextEmbedBlock()); + $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); } } else { if ($isInPlace) { $data = $this->refs[$isInPlace]; } else { - $data[$key] = $this->parseValue($values['value']); + $data[$key] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport); } } } else { // 1-liner followed by newline if (2 == count($this->lines) && empty($this->lines[1])) { try { - $value = Inline::parse($this->lines[0]); + $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine); @@ -345,7 +349,7 @@ private function moveToPreviousLine() * * @throws ParseException When reference does not exist */ - private function parseValue($value) + private function parseValue($value, $exceptionOnInvalidType, $objectSupport) { if (0 === strpos($value, '*')) { if (false !== $pos = strpos($value, '#')) { @@ -368,7 +372,7 @@ private function parseValue($value) } try { - return Inline::parse($value); + return Inline::parse($value, $exceptionOnInvalidType, $objectSupport); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine);
src/Symfony/Component/Yaml/Yaml.php+9 −7 modified@@ -27,7 +27,7 @@ class Yaml * * @deprecated Deprecated since version 2.0, to be removed in 2.3. */ - static public $enablePhpParsing = true; + public static $enablePhpParsing = true; /** * Enables PHP support when parsing YAML files. @@ -89,7 +89,7 @@ public static function supportsPhpParsing() * * @api */ - public static function parse($input) + public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false) { // if input is a file, process it $file = ''; @@ -119,7 +119,7 @@ public static function parse($input) $yaml = new Parser(); try { - return $yaml->parse($input); + return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport); } catch (ParseException $e) { if ($file) { $e->setParsedFile($file); @@ -135,17 +135,19 @@ public static function parse($input) * The dump method, when supplied with an array, will do its best * to convert the array into friendly YAML. * - * @param array $array PHP array - * @param integer $inline The level where you switch to inline YAML + * @param array $array PHP array + * @param integer $inline The level where you switch to inline YAML + * @param Boolean $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param Boolean $objectSupport true if object support is enabled, false otherwise * * @return string A YAML string representing the original PHP array * * @api */ - public static function dump($array, $inline = 2) + public static function dump($array, $inline = 2, $exceptionOnInvalidType = false, $objectSupport = false) { $yaml = new Dumper(); - return $yaml->dump($array, $inline); + return $yaml->dump($array, $inline, $exceptionOnInvalidType, $objectSupport); } }
tests/Symfony/Tests/Component/Yaml/DumperTest.php+18 −3 modified@@ -152,11 +152,26 @@ public function testInlineLevel() $this->assertEquals($expected, $this->dumper->dump($array, 10), '->dump() takes an inline level argument'); } - public function testObjectsSupport() + public function testObjectSupportEnabled() { - $a = array('foo' => new A(), 'bar' => 1); + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, false, true); - $this->assertEquals('{ foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $this->dumper->dump($a), '->dump() is able to dump objects'); + $this->assertEquals('{ foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1)); + + $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\DumpException + */ + public function testObjectSupportDisabledWithExceptions() + { + $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, true, false); } }
tests/Symfony/Tests/Component/Yaml/ParserTest.php+22 −6 modified@@ -13,7 +13,6 @@ use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Parser; -use Symfony\Component\Yaml\Exception\ParseException; class ParserTest extends \PHPUnit_Framework_TestCase { @@ -106,14 +105,31 @@ public function testEndOfTheDocumentMarker() $this->assertEquals('foo', $this->parser->parse($yaml)); } - public function testObjectsSupport() + public function testObjectSupportEnabled() { - $b = array('foo' => new B(), 'bar' => 1); - $this->assertEquals($this->parser->parse(<<<EOF + $input = <<<EOF foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} bar: 1 -EOF - ), $b, '->parse() is able to dump objects'); +EOF; + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $input = <<<EOF +foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + + $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testObjectsSupportDisabledWithExceptions() + { + $this->parser->parse('foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}', true, false); } public function testNonUtf8Exception()
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- symfony.com/blog/security-release-symfony-2-0-22-and-2-1-7-releasednvdVendor AdvisoryWEB
- github.com/advisories/GHSA-7w53-hfpw-rg3gghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2013-1397ghsaADVISORY
- exchange.xforce.ibmcloud.com/vulnerabilities/81551nvdWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/symfony/CVE-2013-1397.yamlghsaWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/yaml/CVE-2013-1397.yamlghsaWEB
- github.com/symfony/symfony/commit/ba6e3159c0eeb3b6e21db32fce8fa2535cb3aa77ghsaWEB
- symfony.com/blog/security-release-symfony-2-0-22-and-2-1-7-releasedghsaWEB
- secunia.com/advisories/51980nvd
- www.securityfocus.com/bid/57574nvd
News mentions
0No linked articles in our index yet.