PostGREShell: в PostgreSQL обнаружили существовавшую 12 лет возможность запуска произвольного кода

1 сентября исследователи Cyera Research раскрыли подробности уязвимости PostGREShell — CVE-2026–6471, позволявшей пользователю PostgreSQL с привилегией REPLICATION загружать произвольные нативные библиотеки в процесс СУБД. Ошибка появилась вместе с механизмом логического декодирования ещё в PostgreSQL 9.4 и оставалась незамеченной около 12 лет. Само исправление было выпущено раньше — 13 августа в PostgreSQL 18.6, 17.11, 16.15, 15.19 и 14.24.
PostgreSQL оценил CVE-2026–6471 в 7,2 балла CVSS. Согласно официальному описанию, пользователь, не являющийся суперпользователем, но имеющий атрибут REPLICATION, мог через механизм логического декодирования заставить сервер выполнить dlopen() произвольного файла, доступного системной учётной записи PostgreSQL. В результате код из библиотеки выполнялся уже не с SQL-правами атакующего, а непосредственно внутри процесса сервера БД.
Механизм, в котором находилась ошибка, появился в PostgreSQL 9.4, выпущенном 18 декабря 2014 года. В этой версии разработчики впервые добавили логическое декодирование WAL, позволяющее преобразовывать журнал изменений базы в поток данных нужного внешнему приложению формата. В дальнейшем эта инфраструктура стала основой для логической репликации и различных систем Change Data Capture. Документация PostgreSQL описывает logical decoding как механизм передачи изменений внешним потребителям через logical replication slots и подключаемые output-плагины.
Для создания logical replication slot клиент указывает имя output-плагина, например штатного pgoutput или стороннего wal2json. Как выяснили исследователи Cyera, именно здесь существовало расхождение между двумя путями загрузки расширений. Обычная SQL-команда LOAD для непривилегированного пользователя выполняет проверку имени библиотеки, тогда как путь загрузки output-плагина через replication protocol такой проверки не выполнял. Переданное клиентом имя могло дойти до системного загрузчика библиотек — dlopen() в Linux и macOS либо LoadLibrary() в Windows.
Для эксплуатации требовалась уже существующая учётная запись PostgreSQL с атрибутом REPLICATION, а для логического декодирования сервер должен работать с wal_level = logical. Это существенно ограничивает круг потенциальных атакующих. В то же время replication-учётные записи используются инфраструктурой репликации, резервного копирования и CDC. О необходимости wal_level = logical для logical decoding также говорится в официальной документации PostgreSQL.
Способ доставки вредоносной библиотеки зависит от операционной системы. На Windows атака может выполняться полностью удалённо: по данным Cyera, в качестве имени библиотеки можно передать UNC-путь вида \\server\share\file.dll. LoadLibrary() в таком случае обращается к SMB-ресурсу, после чего размещённая на сервере атакующего DLL загружается в процесс PostgreSQL. Для этого PostgreSQL-сервер должен иметь возможность установить исходящее SMB-соединение с системой атакующего по TCP/445. Исследователи продемонстрировали такой сценарий в proof-of-concept.
На Linux и macOS ситуация несколько отличается. При настроенном NFS automount исследователи показали похожий вариант с загрузкой библиотеки через /net/.... Однако на обычном Linux, а также в типичной конфигурации Docker или Kubernetes одной учётной записи REPLICATION недостаточно: атакующему необходимо каким-либо другим способом предварительно разместить вредоносный .so в доступной PostgreSQL файловой системе. После этого PostGREShell позволяет заставить сервер загрузить этот файл. Различия способов эксплуатации для Windows, NFS-систем и обычного Linux подробно приведены Cyera.
Загруженная библиотека исполняется в адресном пространстве PostgreSQL с правами системного пользователя сервера. В своём PoC исследователи продемонстрировали дальнейшее повышение привилегий внутри самой СУБД: нативный код может обращаться к внутренним функциям PostgreSQL и изменять системный каталог pg_authid, превращая исходную replication-учётную запись в PostgreSQL superuser в обход обычных SQL ACL.
После получения прав superuser атакующий приобретает доступ ко всем базам и другим привилегированным возможностям PostgreSQL. В техническом разборе Cyera также показаны варианты закрепления после успешной компрометации: изменение pg_hba.conf, добавление вредоносной библиотеки в shared_preload_libraries и восстановление повышенных привилегий после попытки администратора их удалить. Это уже не дополнительные уязвимости PostgreSQL, а демонстрация возможных действий после успешного запуска произвольного нативного кода.
В ходе дополнительного поиска на VirusTotal специалисты Cyera обнаружили 114 вредоносных файлов, оформленных как плагины PostgreSQL, среди которых встречались трояны, майнеры криптовалют и reverse shell. Однако исследование не доказывает, что эти образцы распространялись или загружались при помощи CVE-2026–6471. То есть наличие готовых вредоносных PostgreSQL-плагинов показывает практическую доступность подобной техники, но само по себе не подтверждает эксплуатацию PostGREShell в реальных атаках.
Разработчики PostgreSQL устранили проблему введением нового параметра output_plugin_libraries. Согласно официальным release notes PostgreSQL 18.6, раньше replication-пользователь мог выбрать любую загружаемую библиотеку в качестве logical decoding output plugin. Теперь сервер разрешает только библиотеки из явно определённого списка.
По умолчанию в output_plugin_libraries разрешены только два плагина, поставляемые самим PostgreSQL — pgoutput и test_decoding. Пользователям сторонних output-плагинов после обновления необходимо самостоятельно добавить доверенные библиотеки. Документация параметра приводит, например, такую конфигурацию:
output_plugin_libraries = 'pgoutput, test_decoding, my_trusted_decoder'
При обновлении PostgreSQL с версии 17 и новее pg_upgrade --check также проверяет используемые существующими logical replication slots плагины. Если необходимый плагин отсутствует в output_plugin_libraries нового кластера, проверка завершится ошибкой до тех пор, пока администратор не добавит его в разрешённый список.
Исправление CVE-2026–6471 вошло в выпущенные 13 августа 2026 года PostgreSQL 18.6, 17.11, 16.15, 15.19 и 14.24. Официальная карточка PostgreSQL указывает все эти версии как первые исправленные выпуски. Более старые неподдерживаемые ветки отдельных security-релизов уже не получают, поэтому их пользователям требуется переход на поддерживаемую версию PostgreSQL.
Помимо установки обновлений, Cyera рекомендует провести аудит всех ролей с атрибутом REPLICATION, удалить эти права у учётных записей, которым они больше не требуются, и ограничить источники подключения replication-пользователей через pg_hba.conf. Для PostgreSQL-серверов также рекомендуется блокировать ненужные исходящие соединения SMB/445 и NFS/2049, отключать ненужный autofs и отслеживать создание неожиданных replication slots и имена output-плагинов, содержащие /, \ или ...
Уязвимость была передана PostgreSQL Security Team Владимиром Токаревым 21 февраля 2026 года, а 27 февраля команда PostgreSQL подтвердила наличие проблемы. В официальных release notes PostgreSQL за обнаружение CVE-2026–6471 выражена благодарность Vladimir Tokarev и Yu Kunpeng, а автором изменения, вводящего output_plugin_libraries, указан Jacob Champion.
>>> Источник
