Уязвимости в ядре PHP: стандартные функции обработки изображений оказались опасными

php

PHP остаётся одним из самых распространённых языков для веб-разработки. Обычно внимание специалистов по информационной безопасности сосредоточено на фреймворках и сторонних библиотеках. Однако новое исследование показывает, что даже встроенные возможности самого PHP, а именно стандартное расширение ext/standard, могут таить в себе серьёзные риски при обработке непроверенных данных, например файлов изображений.

Исследователи из PT Swarm обнаружили две проблемы с безопасностью управления памятью, затрагивающие нативные функции обработки изображений. Речь идёт об утечке содержимого кучи (области динамической памяти) в функции getimagesize() и переполнении буфера кучи в функции iptcembed(). Первая уязвимость получила идентификатор CVE-2025-14177 с базовой оценкой CVSS 6,3 (шкала критичности уязвимостей от 0 до 10). Вторая пока не имеет официального номера, но не менее опасна.

Как работает PHP изнутри

Чтобы понять суть проблемы, нужно немного углубиться в архитектуру языка. В основе PHP лежит Zend Engine - среда выполнения, которая компилирует и исполняет скрипты. В её состав входят виртуальная машина Zend VM, компилятор, менеджер памяти и кеш OPcache для ускорения работы. Когда скрипт обрабатывает изображение, встроенные функции взаимодействуют с системной памятью напрямую через код на C. Именно поэтому они особенно чувствительны к ошибкам управления памятью.

Расширение ext/standard предоставляет сотни базовых функций, включая работу с файлами и разбор метаданных изображений. Поскольку эти функции обрабатывают данные, поступающие от пользователя (например, загруженные картинки), любые уязвимости в этом слое могут иметь широкий радиус поражения.

Первая уязвимость: утечка памяти из кучи

Функция getimagesize() используется для получения размеров и типа изображения. Проблема кроется в том, как она обрабатывает JPEG-файлы с большими сегментами APP, такими как блоки EXIF (метаданные, встраиваемые в снимки цифровых камер). Когда PHP считывает крупные метаданные частями, он неправильно записывает каждый фрагмент в одну и ту же область памяти, вместо того чтобы дописывать их последовательно. В результате начало буфера перезаписывается, а его хвост остаётся неинициализированным.

Это приводит к тому, что пользователь может получить остатки данных из серверной памяти, которые не были стёрты. Представьте: злоумышленник создаёт специально сформированный JPEG-файл с большим сегментом APP1 (EXIF). Если он знает стандартный размер фрагмента (обычно 8192 байта), он может организовать файл так, чтобы после обработки ему вернулись фрагменты оперативной памяти серверного процесса. Исследователи подтвердили эту возможность, поместив в память специальные метки и считав их через уязвимую функцию.

Вторая уязвимость: переполнение буфера

Функция iptcembed() встраивает IPTC-метаданные (ещё один стандарт описания изображений, используемый в журналистике) в JPEG. Здесь проблема гораздо серьёзнее. Причина в том, как PHP выделяет память: он вызывает системный вызов fstat(), чтобы узнать размер файла, и выделяет буфер соответствующего объёма. Но затем продолжает читать данные до самого конца файла (EOF), не проверяя, не вышел ли он за границы буфера.

Особенно опасна эта ошибка при работе с нестандартными файлами, например с именованными каналами (FIFO). Для таких объектов системная функция fstat() возвращает нулевой размер. В этом случае PHP выделяет крошечный буфер, а входной поток продолжает поступать. В результате данные записываются за пределы выделенной памяти - происходит переполнение буфера кучи. Исследователи продемонстрировали это, используя FIFO-канал, через который передавался специально подготовленный JPEG с большой полезной нагрузкой. Инструмент AddressSanitizer (средство обнаружения ошибок памяти) подтвердил переполнение, что указывает на реальную возможность эксплуатации.

Как исправили проблемы

Разработчики PHP уже выпустили патчи для обеих уязвимостей. Для getimagesize() теперь указатель буфера правильно сдвигается после каждого чтения фрагмента, что предотвращает как перезапись, так и утечку неинициализированной памяти. Для iptcembed() добавлена строгая проверка границ: запись останавливается, как только достигнут лимит выделенного буфера, а функция безопасно завершает обработку.

Что это значит для разработчиков и пользователей

Эти находки подчёркивают важный урок: даже зрелые и широко используемые компоненты среды выполнения могут содержать скрытые, но опасные дефекты, особенно если они написаны на низкоуровневых языках вроде C. Для команд разработки и специалистов по безопасности вывод очевиден: функциям, обрабатывающим файлы, особенно изображения, не следует слепо доверять. Проверка входных данных, ограничение размера файлов и своевременное обновление PHP - необходимые шаги для снижения риска.

Атаки через метаданные изображений становятся всё более популярным вектором. Поэтому каждый слой приложения, даже тот, который долгое время считался безопасным, заслуживает пристального внимания. В данном случае уязвимости были найдены в стандартной библиотеке PHP - то есть в коде, который выполняется на миллионах серверов по всему миру. Хорошая новость в том, что исправления уже доступны, и администраторам нужно лишь установить последнюю версию языка.

Ссылки

Комментарии: 0