High severity8.0NVD Advisory· Published May 14, 2024· Updated Apr 28, 2026
CVE-2024-29800
CVE-2024-29800
Description
Deserialization of Untrusted Data vulnerability in Timber Team & Contributors Timber.This issue affects Timber: from n/a through 1.23.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
timber/timberPackagist | >= 2.0.0, < 2.1.0 | 2.1.0 |
timber/timberPackagist | >= 1.24.0, < 1.24.1 | 1.24.1 |
timber/timberPackagist | >= 0.16.6, < 1.23.1 | 1.23.1 |
Patches
113c6b0f60346fix: Add patch for PHAR deserialization vulnerability for Timber 2.x (security advisory GHSA-6363-v5m4-fvq3)
7 files changed · +136 −1
src/Attachment.php+5 −0 modified@@ -2,6 +2,7 @@ namespace Timber; +use InvalidArgumentException; use Timber\Factory\PostFactory; /** @@ -245,6 +246,10 @@ public function size(): ?int return $this->size = (int) $size; } + if (!ImageHelper::is_protocol_allowed($this->file_loc())) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + /** * Filesize wasn't found in the metadata, so we'll try to get it from the file itself. *
src/ImageDimensions.php+6 −0 modified@@ -2,6 +2,8 @@ namespace Timber; +use InvalidArgumentException; + /** * Class FileSize * @@ -117,6 +119,10 @@ public function get_dimension($dimension): ?int return $this->get_dimension_loaded($dimension); } + if (!ImageHelper::is_protocol_allowed($this->file_loc)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + // Load dimensions. if (\file_exists($this->file_loc) && \filesize($this->file_loc)) { if (ImageHelper::is_svg($this->file_loc)) {
src/ImageHelper.php+60 −1 modified@@ -2,6 +2,7 @@ namespace Timber; +use InvalidArgumentException; use Timber\Image\Operation; /** @@ -29,6 +30,10 @@ class ImageHelper public static $home_url; + protected const ALLOWED_PROTOCOLS = ['file', 'http', 'https']; + + protected const WINDOWS_LOCAL_FILENAME_REGEX = '/^[a-z]:(?:[\\\\\/]?(?:[\w\s!#()-]+|[\.]{1,2})+)*[\\\\\/]?/i'; + /** * Inits the object. */ @@ -140,6 +145,11 @@ public static function is_animated_gif($file) //doesn't have .gif, bail return false; } + + if (!ImageHelper::is_protocol_allowed($file)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + // Its a gif so test if (!($fh = @\fopen($file, 'rb'))) { return false; @@ -169,7 +179,15 @@ public static function is_animated_gif($file) */ public static function is_svg($file_path) { - if ('' === $file_path || !\file_exists($file_path)) { + if ('' === $file_path) { + return false; + } + + if (!ImageHelper::is_protocol_allowed($file_path)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + + if (!\file_exists($file_path)) { return false; } @@ -431,6 +449,10 @@ public static function get_sideloaded_file_loc($file) */ public static function sideload_image($file) { + if (!ImageHelper::is_protocol_allowed($file)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + /** * Adds a filter to change the upload folder temporarily. * @@ -444,6 +466,7 @@ public static function sideload_image($file) \add_filter('upload_dir', [__CLASS__, 'set_sideload_image_upload_dir']); $loc = self::get_sideloaded_file_loc($file); + if (\file_exists($loc)) { $url = URLHelper::file_system_to_url($loc); @@ -806,6 +829,10 @@ private static function _operate($src, $op, $force = false) return ''; } + if (!ImageHelper::is_protocol_allowed($src)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + $allow_fs_write = \apply_filters('timber/allow_fs_write', true); if ($allow_fs_write === false) { @@ -949,4 +976,36 @@ public static function get_resize_file_path($url, $w, $h, $crop) ); return $new_path; } + + /** + * Checks if the protocol of the given filename is allowed. + * + * This fixes a security issue with a PHAR deserialization vulnerability + * with file_exists() in PHP < 8.0.0. + * + * @param string $filepath File path. + * @return bool + */ + public static function is_protocol_allowed($filepath) + { + $parsed_url = \parse_url($filepath); + + if (false === $parsed_url) { + throw new InvalidArgumentException('The filename is not valid.'); + } + + $protocol = isset($parsed_url['scheme']) + ? \mb_strtolower($parsed_url['scheme']) + : 'file'; + + if ( + \PHP_OS_FAMILY === 'Windows' + && \strlen($protocol) === 1 + && \preg_match(self::WINDOWS_LOCAL_FILENAME_REGEX, $filepath) + ) { + $protocol = 'file'; + } + + return \in_array($protocol, self::ALLOWED_PROTOCOLS, true); + } }
src/Image/Operation/ToJpg.php+5 −0 modified@@ -2,6 +2,7 @@ namespace Timber\Image\Operation; +use InvalidArgumentException; use Timber\Image\Operation as ImageOperation; use Timber\ImageHelper; @@ -44,6 +45,10 @@ public function filename($src_filename, $src_extension = 'jpg') */ public function run($load_filename, $save_filename) { + if (!ImageHelper::is_protocol_allowed($load_filename)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + if (!\file_exists($load_filename)) { return false; }
src/Image/Operation/ToWebp.php+5 −0 modified@@ -2,6 +2,7 @@ namespace Timber\Image\Operation; +use InvalidArgumentException; use Timber\Helper; use Timber\Image\Operation as ImageOperation; use Timber\ImageHelper; @@ -45,6 +46,10 @@ public function filename($src_filename, $src_extension = 'webp') */ public function run($load_filename, $save_filename) { + if (!ImageHelper::is_protocol_allowed($load_filename)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + if (!\is_file($load_filename)) { return false; }
src/Timber.php+5 −0 modified@@ -2,6 +2,7 @@ namespace Timber; +use InvalidArgumentException; use Timber\Factory\CommentFactory; use Timber\Factory\MenuFactory; use Timber\Factory\PagesMenuFactory; @@ -659,6 +660,10 @@ public static function get_attachment_by(string $field_or_ident, string $ident = return null; } + if (!ImageHelper::is_protocol_allowed($ident)) { + throw new InvalidArgumentException('The output file scheme is not supported.'); + } + if (!\file_exists($ident)) { // Deal with a relative path. $ident = URLHelper::get_full_path($ident);
tests/test-timber-image.php+50 −0 modified@@ -1185,4 +1185,54 @@ public function testSVGDimensions() $this->assertSame(23, $image->width()); $this->assertSame(20, $image->height()); } + + public function testPharProtocolIsNotAllowedwithResize() + { + $object = new ImageOperation\Resize(400, 300, 'center'); + $load_filename = 'phar://test.jpg'; + $save_filename = 'test-new.jpg'; + + $this->expectException(InvalidArgumentException::class); + $object->run($load_filename, $save_filename); + } + + public function testPharProtocolIsNotAllowedwithLetterbox() + { + $object = new ImageOperation\Letterbox(400, 300, '#FFFFFF'); + $load_filename = 'phar://test.jpg'; + $save_filename = 'test-new.jpg'; + + $this->expectException(InvalidArgumentException::class); + $object->run($load_filename, $save_filename); + } + + public function testPharProtocolIsNotAllowedwithRetina() + { + $object = new ImageOperation\Retina(2); + $load_filename = 'phar://test.jpg'; + $save_filename = 'test-new.jpg'; + + $this->expectException(InvalidArgumentException::class); + $object->run($load_filename, $save_filename); + } + + public function testPharProtocolIsNotAllowedwithToJpg() + { + $object = new ImageOperation\ToJpg('#FFFFFF'); + $load_filename = 'phar://test.svg'; + $save_filename = 'test-new.svg'; + + $this->expectException(InvalidArgumentException::class); + $object->run($load_filename, $save_filename); + } + + public function testPharProtocolIsNotAllowedwithToWebp() + { + $object = new ImageOperation\ToWebp(80); + $load_filename = 'phar://test.png'; + $save_filename = 'test-new.png'; + + $this->expectException(InvalidArgumentException::class); + $object->run($load_filename, $save_filename); + } }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-6363-v5m4-fvq3ghsaADVISORY
- github.com/FriendsOfPHP/security-advisories/blob/master/timber/timber/CVE-2024-29800.yamlghsaWEB
- github.com/timber/timber/commit/13c6b0f60346304f2eed4da1e0bb51566518de4aghsaWEB
- github.com/timber/timber/issues/2971ghsaWEB
- github.com/timber/timber/security/advisories/GHSA-6363-v5m4-fvq3ghsaWEB
- patchstack.com/database/vulnerability/timber-library/wordpress-timber-plugin-1-23-0-deserialization-of-untrusted-data-vulnerabilitynvd
News mentions
0No linked articles in our index yet.