diff options
Diffstat (limited to 'modules/openid/openid.inc')
-rw-r--r-- | modules/openid/openid.inc | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/modules/openid/openid.inc b/modules/openid/openid.inc index 9b793d368..3c8281540 100644 --- a/modules/openid/openid.inc +++ b/modules/openid/openid.inc @@ -138,8 +138,28 @@ function openid_redirect_form($form, &$form_state, $url, $message) { */ function _openid_xrds_parse($raw_xml) { $services = array(); - try { - $xml = @new SimpleXMLElement($raw_xml); + + // For PHP version >= 5.2.11, we can use this function to protect against + // malicious doctype declarations and other unexpected entity loading. + // However, we will not rely on it, and reject any XML with a DOCTYPE. + $disable_entity_loader = function_exists('libxml_disable_entity_loader'); + if ($disable_entity_loader) { + $load_entities = libxml_disable_entity_loader(TRUE); + } + + // Load the XML into a DOM document. + $dom = new DOMDocument(); + @$dom->loadXML($raw_xml); + + // Since DOCTYPE declarations from an untrusted source could be malicious, we + // stop parsing here and treat the XML as invalid since XRDS documents do not + // require, and are not expected to have, a DOCTYPE. + if (isset($dom->doctype)) { + return array(); + } + + // Parse the DOM document for the information we need. + if ($xml = simplexml_import_dom($dom)) { foreach ($xml->children(OPENID_NS_XRD)->XRD as $xrd) { foreach ($xrd->children(OPENID_NS_XRD)->Service as $service_element) { $service = array( @@ -165,9 +185,12 @@ function _openid_xrds_parse($raw_xml) { } } } - catch (Exception $e) { - // Invalid XML. + + // Return the LIBXML options to the previous state before returning. + if ($disable_entity_loader) { + libxml_disable_entity_loader($load_entities); } + return $services; } |