Skip to content

Commit 93998d3

Browse files
committed
Merge branch '2.0'
* 2.0: updated VERSION for 2.0.17 updated CHANGELOG for 2.0.17 updated vendors for 2.0.17 fixed XML decoding attack vector through external entities prevents injection of malicious doc types disabled network access when loading XML documents refined previous commit prevents injection of malicious doc types standardized the way we handle XML errors Redirects are now absolute Conflicts: CHANGELOG-2.0.md src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php src/Symfony/Component/DomCrawler/Crawler.php src/Symfony/Component/HttpKernel/Kernel.php tests/Symfony/Tests/Component/DependencyInjection/Loader/XmlFileLoaderTest.php tests/Symfony/Tests/Component/Routing/Loader/XmlFileLoaderTest.php tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php tests/Symfony/Tests/Component/Translation/Loader/XliffFileLoaderTest.php tests/Symfony/Tests/Component/Validator/Mapping/Loader/XmlFileLoaderTest.php vendors.php
2 parents 5088ecb + 8760b89 commit 93998d3

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

Encoder/XmlEncoder.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,20 @@ public function decode($data, $format)
5858
$disableEntities = libxml_disable_entity_loader(true);
5959
libxml_clear_errors();
6060

61-
$xml = simplexml_load_string($data);
61+
$dom = new \DOMDocument();
62+
$dom->loadXML($data, LIBXML_NONET);
63+
6264
libxml_use_internal_errors($internalErrors);
6365
libxml_disable_entity_loader($disableEntities);
6466

67+
foreach ($dom->childNodes as $child) {
68+
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
69+
throw new UnexpectedValueException('Document types are not allowed.');
70+
}
71+
}
72+
73+
$xml = simplexml_import_dom($dom);
74+
6575
if ($error = libxml_get_last_error()) {
6676
throw new UnexpectedValueException($error->message);
6777
}

Tests/Encoder/XmlEncoderTest.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ public function testSetRootNodeName()
5050
$this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
5151
}
5252

53+
/**
54+
* @expectedException UnexpectedValueException
55+
* @expectedExceptionMessage Document types are not allowed.
56+
*/
57+
public function testDocTypeIsNotAllowed()
58+
{
59+
$this->encoder->decode('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'foo');
60+
}
61+
5362
public function testAttributes()
5463
{
5564
$obj = new ScalarDummy;
@@ -242,20 +251,22 @@ public function testDecodeArray()
242251
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
243252
}
244253

245-
/**
246-
* @expectedException Symfony\Component\Serializer\Exception\UnexpectedValueException
247-
*/
248254
public function testPreventsComplexExternalEntities()
249255
{
250256
$oldCwd = getcwd();
251257
chdir(__DIR__);
252258

253259
try {
254-
$decoded = $this->encoder->decode('<?xml version="1.0"?><!DOCTYPE scan[<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=XmlEncoderTest.php">]><scan>&test;</scan>', 'xml');
260+
$this->encoder->decode('<?xml version="1.0"?><!DOCTYPE scan[<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=XmlEncoderTest.php">]><scan>&test;</scan>', 'xml');
255261
chdir($oldCwd);
256-
} catch (UnexpectedValueException $e) {
262+
263+
$this->fail('No exception was thrown.');
264+
} catch (\Exception $e) {
257265
chdir($oldCwd);
258-
throw $e;
266+
267+
if (!$e instanceof UnexpectedValueException) {
268+
$this->fail('Expected UnexpectedValueException');
269+
}
259270
}
260271
}
261272

0 commit comments

Comments
 (0)