Skip to content

Commit 393590a

Browse files
AngelFQCclaude
andcommitted
Security: harden user-import XML parsing against XXE
The user import/update XML parsing relied entirely on the libxml runtime default to avoid external entity resolution, leaving the code unhardened on PHP < 8 or misconfigured environments. Explicitly block external entity loading with a null libxml_set_external_entity_loader() around each addXmlContent() call (user import and update flows), restoring the default loader afterwards. This is the non-deprecated, PHP 8.x-safe equivalent and does not enable entity substitution (LIBXML_NOENT is intentionally not used). Refs GHSA-h24x-xw47-2wwx Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4ebcf1a commit 393590a

3 files changed

Lines changed: 12 additions & 0 deletions

File tree

public/main/admin/user_import.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,12 @@ function parse_csv_data($users, $fileName, $sendEmail = 0, $checkUniqueEmail = t
451451
*/
452452
function parse_xml_data($file)
453453
{
454+
// XXE hardening: block loading of any external entity regardless of the
455+
// libxml runtime default, then restore the default loader.
456+
libxml_set_external_entity_loader(static fn () => null);
454457
$crawler = new \Symfony\Component\DomCrawler\Crawler();
455458
$crawler->addXmlContent(file_get_contents($file));
459+
libxml_set_external_entity_loader(null);
456460
$crawler = $crawler->filter('Contacts > Contact ');
457461
$array = [];
458462
foreach ($crawler as $domElement) {

public/main/admin/user_update_import.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,12 @@ function parse_csv_data($file)
247247

248248
function parse_xml_data($file)
249249
{
250+
// XXE hardening: block loading of any external entity regardless of the
251+
// libxml runtime default, then restore the default loader.
252+
libxml_set_external_entity_loader(static fn () => null);
250253
$crawler = new Crawler();
251254
$crawler->addXmlContent(file_get_contents($file));
255+
libxml_set_external_entity_loader(null);
252256
$crawler = $crawler->filter('Contacts > Contact ');
253257
$array = [];
254258
foreach ($crawler as $domElement) {

public/main/inc/lib/myspace.lib.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3106,8 +3106,12 @@ public static function parse_csv_data($file)
31063106
*/
31073107
public static function parse_xml_data($file)
31083108
{
3109+
// XXE hardening: block loading of any external entity regardless of the
3110+
// libxml runtime default, then restore the default loader.
3111+
libxml_set_external_entity_loader(static fn () => null);
31093112
$crawler = new \Symfony\Component\DomCrawler\Crawler();
31103113
$crawler->addXmlContent(file_get_contents($file));
3114+
libxml_set_external_entity_loader(null);
31113115
$crawler = $crawler->filter('Contacts > Contact ');
31123116
$array = [];
31133117
foreach ($crawler as $domElement) {

0 commit comments

Comments
 (0)