mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
BUG Fix SS-2014-017
This commit is contained in:
parent
80fc55decf
commit
7f983c2bae
@ -167,15 +167,32 @@ class Convert {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an XML string to a PHP array
|
* Converts an XML string to a PHP array
|
||||||
|
* See http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#xml-external-entity-injection
|
||||||
*
|
*
|
||||||
* @uses recursiveXMLToArray()
|
* @uses recursiveXMLToArray()
|
||||||
* @param string
|
* @param string $val
|
||||||
*
|
* @param boolean $disableDoctypes Disables the use of DOCTYPE, and will trigger an error if encountered.
|
||||||
|
* false by default.
|
||||||
|
* @param boolean $disableExternals Disables the loading of external entities. false by default.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function xml2array($val) {
|
public static function xml2array($val, $disableDoctypes = false, $disableExternals = false) {
|
||||||
|
// Check doctype
|
||||||
|
if($disableDoctypes && preg_match('/\<\!DOCTYPE.+]\>/', $val)) {
|
||||||
|
throw new InvalidArgumentException('XML Doctype parsing disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable external entity loading
|
||||||
|
if($disableExternals) $oldVal = libxml_disable_entity_loader($disableExternals);
|
||||||
|
try {
|
||||||
$xml = new SimpleXMLElement($val);
|
$xml = new SimpleXMLElement($val);
|
||||||
return self::recursiveXMLToArray($xml);
|
$result = self::recursiveXMLToArray($xml);
|
||||||
|
} catch(Exception $ex) {
|
||||||
|
if($disableExternals) libxml_disable_entity_loader($oldVal);
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
if($disableExternals) libxml_disable_entity_loader($oldVal);
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,4 +238,55 @@ class ConvertTest extends SapphireTest {
|
|||||||
Convert::raw2json($value)
|
Convert::raw2json($value)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testXML2Array() {
|
||||||
|
// Ensure an XML file at risk of entity expansion can be avoided safely
|
||||||
|
$inputXML = <<<XML
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]>
|
||||||
|
<results>
|
||||||
|
<result>Now include &long; lots of times to expand the in-memory size of this XML structure</result>
|
||||||
|
<result>&long;&long;&long;</result>
|
||||||
|
</results>
|
||||||
|
XML
|
||||||
|
;
|
||||||
|
try {
|
||||||
|
Convert::xml2array($inputXML, true);
|
||||||
|
} catch(Exception $ex) {}
|
||||||
|
$this->assertTrue(
|
||||||
|
isset($ex)
|
||||||
|
&& $ex instanceof InvalidArgumentException
|
||||||
|
&& $ex->getMessage() === 'XML Doctype parsing disabled'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test without doctype validation
|
||||||
|
$expected = array(
|
||||||
|
'result' => array(
|
||||||
|
"Now include SOME_SUPER_LONG_STRING lots of times to expand the in-memory size of this XML structure",
|
||||||
|
array(
|
||||||
|
'long' => array(
|
||||||
|
array(
|
||||||
|
'long' => 'SOME_SUPER_LONG_STRING'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'long' => 'SOME_SUPER_LONG_STRING'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'long' => 'SOME_SUPER_LONG_STRING'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$result = Convert::xml2array($inputXML, false, true);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$result
|
||||||
|
);
|
||||||
|
$result = Convert::xml2array($inputXML, false, false);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$result
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user