From 2756af23a3561a31fd14f644b116ed94270b0a27 Mon Sep 17 00:00:00 2001 From: XananasX7 Date: Sun, 31 May 2026 03:16:36 +0000 Subject: [PATCH] security: add allowed_classes => false to LogTarget unserialize() calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The debug LogTarget serializes and deserializes panel data to/from the filesystem (debug data path). Without allowed_classes => false, an attacker who can write to the debug data directory can inject a PHP Object Injection payload that triggers a gadget chain when the Craft debug module renders. All four call sites operate on data produced by Panel::save() which returns plain PHP arrays of scalars — no objects are ever legitimately stored: - getIndexFile(): reads summary index → array of scalar summaries - loadTagToPanels(): reads per-tag outer array + per-panel arrays - _updateIndexFile(): reads existing manifest array Add allowed_classes => false to all four unserialize() calls as defence-in-depth. --- src/debug/LogTarget.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/debug/LogTarget.php b/src/debug/LogTarget.php index d851f7c1c24..61bc1f4a23e 100644 --- a/src/debug/LogTarget.php +++ b/src/debug/LogTarget.php @@ -73,7 +73,7 @@ public function loadManifest(): array $content = $this->module->fs->read($indexFile); if ($content !== '') { - return array_reverse(unserialize($content), true); + return array_reverse(unserialize($content, ['allowed_classes' => false]), true); } return []; @@ -89,12 +89,12 @@ public function loadTagToPanels($tag): array } $dataFile = $this->module->dataPath . "/$tag.data"; - $data = unserialize($this->module->fs->read($dataFile)); + $data = unserialize($this->module->fs->read($dataFile), ['allowed_classes' => false]); $exceptions = $data['exceptions']; foreach ($this->module->panels as $id => $panel) { if (isset($data[$id])) { $panel->tag = $tag; - $panel->load(unserialize($data[$id])); + $panel->load(unserialize($data[$id], ['allowed_classes' => false])); } if (isset($exceptions[$id])) { $panel->setError($exceptions[$id]); @@ -168,7 +168,7 @@ protected function removeStaleDataFiles($manifest): void private function _updateIndexFile(string $indexFile, array $summary): void { try { - $manifest = unserialize($this->module->fs->read($indexFile)); + $manifest = unserialize($this->module->fs->read($indexFile), ['allowed_classes' => false]); } catch (FsException $e) { $manifest = []; }