Skip to content

Commit

Permalink
prevents injection of malicious doc types
Browse files Browse the repository at this point in the history
  • Loading branch information
schmittjoh authored and fabpot committed Aug 28, 2012
1 parent 865461d commit a2a6cdc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
12 changes: 12 additions & 0 deletions src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
Expand Up @@ -54,6 +54,7 @@ public function encode($data, $format)
*/
public function decode($data, $format)
{
$this->assertNoCustomDocType($data);
$internalErrors = libxml_use_internal_errors(true);
$disableEntities = libxml_disable_entity_loader(true);
libxml_clear_errors();
Expand Down Expand Up @@ -290,6 +291,17 @@ private function buildXml($parentNode, $data)
throw new UnexpectedValueException('An unexpected value could not be serialized: '.var_export($data, true));
}

private function assertNoCustomDocType($data)
{
$dom = new \DOMDocument;
$dom->loadXML($data);
foreach ($dom->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
throw new \InvalidArgumentException('Document types are not allowed.');
}
}
}

/**
* Selects the type of node to create and appends it to the parent.
*
Expand Down
Expand Up @@ -53,6 +53,15 @@ public function testSetRootNodeName()
$this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Document types are not allowed.
*/
public function testDocTypeIsNotAllowed()
{
$this->encoder->decode('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'foo');
}

public function testAttributes()
{
$obj = new ScalarDummy;
Expand Down Expand Up @@ -233,20 +242,22 @@ public function testDecodeArray()
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
}

/**
* @expectedException Symfony\Component\Serializer\Exception\UnexpectedValueException
*/
public function testPreventsComplexExternalEntities()
{
$oldCwd = getcwd();
chdir(__DIR__);

try {
$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');
$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');
chdir($oldCwd);
} catch (UnexpectedValueException $e) {

$this->fail('No exception was thrown.');
} catch (\Exception $e) {
chdir($oldCwd);
throw $e;

if (!$e instanceof \InvalidArgumentException) {
$this->fail('Expected InvalidArgumentException');
}
}
}

Expand Down

0 comments on commit a2a6cdc

Please sign in to comment.