Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/0xmrma/cve-2026-45806
Анализ уязвимостейЭксплуатацияВеб-безопасностьТестирование на ПроникновениеСтатьи и ИсследованияОбучение и Образование
GitHub0xmrma/cve-2026-45806

CVE-2026-45806

Репозиторий
63 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →

Описание

Функция импорта удаленных изображений в Penpot позволяет аутентифицированному редактору файлов превратить обычную медиа-функцию в SSRF с серверной стороны, поскольку управляемые атакующим URL попадали в путь загрузки сервера, который следует за перенаправлениями, без фильтрации назначения.

Поделиться

CVE-2026-45806

Импорт удаленных изображений в Penpot позволял аутентифицированному редактору файлов превратить обычную функцию работы с медиа в SSRF из бэкенда, поскольку управляемые атакующим URL попадали в путь выборки с сервера, который следовал перенаправлениям без фильтрации целевых адресов.

Введение

Я нашел эту проблему при анализе Penpot, платформы с открытым исходным кодом для совместного дизайна и кода, задавшись очень конкретным вопросом:

Что происходит, когда инструмент совместного дизайна позволяет одному пользователю передать бэкенду URL удаленного изображения для загрузки?

В данном случае этот вопрос привел к реальной ошибке.

Поток импорта удаленных изображений Penpot принимал управляемый пользователем URL и заставлял бэкенд загружать его из серверного сетевого контекста без применения ограничений на целевые адреса loopback или частных сетей. Общий HTTP-клиент также автоматически следовал перенаправлениям.

Это превратило обычную функцию работы с медиа в примитив аутентифицированного SSRF из бэкенда, что в итоге привело к CVE-2026-45806.

Penpot: Penpot на GitHub
CVE: CVE-2026-45806
CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N

Это затронуло Penpot. На своем официальном сайте и в медиа-ките Penpot позиционирует себя как платформа с пользовательской базой, превышающей 1 млн человек, и сообщает, что десятки тысяч организаций используют ее, включая Blender, Mozilla, Fedora, NTT Data, MIT, Société Générale, Cisco, Fujitsu, Indra и ByteDance.

photo0

Цепочка атаки

аутентифицированный редактор файлов -> управляемый атакующим URL удаленного изображения -> create-file-media-object-from-url -> загрузка изображения бэкендом fetch с включенными перенаправлениями -> итоговый запрос попадает на внутреннюю конечную точку, возвращающую изображение -> SSRF из бэкенда / достижимость внутренних ресурсов


Что делает Penpot

Penpot — это платформа с открытым исходным кодом для совместного дизайна и кода.

Она обрабатывает такие вещи, как:

  • совместное редактирование файлов
  • рабочие процессы команд и проектов
  • загруженные медиа и ресурсы
  • пути рендеринга и предварительного просмотра
  • операции дизайна на основе браузера с обработкой на стороне сервера

Это означает, что ее путь импорта медиа находится на реальной границе доверия.

Важный вопрос здесь заключался не в том, поддерживает ли Penpot импорт удаленных изображений.

Настоящий вопрос был таким:

Ограничивает ли Penpot, куда бэкенду разрешено подключаться, когда пользователь импортирует удаленное изображение?

В данном случае — нет.


Почему эта ошибка заслуживала внимания

Многие недооценивают функции удаленного импорта.

Это ошибка.

Как только приложение:

  • принимает управляемый атакующим URL,
  • выполняет запрос с бэкенда,
  • и превращает этот запрос в обычный рабочий процесс продукта,

оно создает реальную границу доверия исходящих соединений.

В этом и была проблема.

Эта ошибка была не в рендеринге изображений. Не в хранении файлов. Не в обычных проверках разрешений на редактирование файла.

Это была классическая серверная ошибка доверия:

  • управляемый атакующим URL попал в систему,
  • бэкенд выполнил к нему запрос напрямую,
  • перенаправления были разрешены,
  • и в проверенном пути не было видимого контроля целевых адресов.

Этого достаточно, чтобы создать реальную уязвимость.


Граница, на которой я сосредоточился

Я не подходил к Penpot, слепо фаззя случайные RPC-методы или ища сбои в первую очередь.

Более сильным подходом было определить наиболее перспективную границу безопасности.

Для Penpot это был удаленный импорт медиа.

Почему?

Потому что эта функция сочетает:

  • ввод URL, контролируемый атакующим
  • исходящие запросы из бэкенда
  • проверку содержимого, которая происходит только после выполнения запроса
  • рабочий процесс дизайна, где успешные загрузки считаются обычными медиа-операциями

Это была правильная граница для проверки.

И именно здесь жила ошибка.


Коренная причина

Ошибка сводится к короткой цепочке доверия.

Во фронтенде:

(defn upload-media-url
  [name file-id url]
  (rp/cmd!
   :create-file-media-object-from-url
   {:name name
    :file-id file-id
    :url url
    :is-local true}))

управляемый пользователем url напрямую передается в RPC-вызов.

Затем в бэкенде:

(sv/defmethod ::create-file-media-object-from-url
  ...
  [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
  (files/check-edition-permissions! pool profile-id file-id)
  ...
  (let [_    (files/get-minimal-file cfg file-id)
        mobj (create-file-media-object-from-url cfg (assoc params :profile-id profile-id))])

и:

(defn- create-file-media-object-from-url
  [cfg {:keys [url name] :as params}]
  (let [content (media/download-image cfg url)

бэкенд проверяет, что вызывающий может редактировать целевой файл, а затем передает управляемый атакующим URL в media/download-image.

Реализация выборки находится здесь:

(defn download-image
  "Download an image from the provided URI and return the media input object"
  [{:keys [::http/client]} uri]
  ...
  (http/req! client
             {:method :get :uri uri}
             {:response-type :input-stream})

А общий HTTP-клиент настроен так:

(http/build-client {:connect-timeout 30000
                    :follow-redirects :always}))

Вот и вся уязвимость:

  • атакующий управляет URL
  • бэкенд выполняет запрос
  • перенаправления выполняются автоматически
  • фильтрация целевых адресов перед запросом не применяется

Почему это эксплуатируемо

Потому что атакующему нужно только:

  • действующая учетная запись Penpot
  • разрешение на редактирование одного файла
  • цель, которая возвращает принятое содержимое изображения

Цепочка атаки проста:

  • атакующий предоставляет URL
  • Penpot загружает его с бэкенда
  • начальный переход может быть публичным или безобидным
  • цель перенаправления может быть внутренней
  • если итоговый ответ выглядит как разрешенное изображение, импорт завершается

Вот и вся ошибка.


Что делает это проблемой безопасности, а не просто обычным импортом удаленных изображений

Важное различие заключается в том, где выполняется запрос.

Вопрос не в том:

«Может ли Penpot импортировать изображения по URL?»

Реальный вопрос:

«Может ли аутентифицированный пользователь заставить бэкенд Penpot подключаться к внутренним адресам, к которым пользователь не должен иметь доступ через приложение?»

В данном случае ответ был «да».

Это важно, потому что есть реальная разница между:

  • браузером, загружающим предоставленный пользователем URL, и
  • бэкендом, загружающим этот URL из сетевого положения сервера

Валидация изображений не устраняет эту разницу.

Она сужает некоторые случаи прямой эксфильтрации, но не устраняет условие SSRF или нарушение сетевой границы.


PoC

Я подтвердил эту проблему с помощью контролируемого локального доказательства, напрямую связанного с проверенным кодом Penpot.

Целью было не воздействие на стороннюю инфраструктуру. Целью было доказать точное свойство безопасности:

  • выполнение запроса в стиле бэкенда
  • следование перенаправлениям
  • успешный переход на внутреннюю конечную точку
  • завершение при тех же ограничениях, связанных с изображениями, которые применяет Penpot

Я создал автономный валидатор на Java, который повторял соответствующее поведение:

  • GET-запрос со стороны бэкенда к URI, контролируемому вызывающим
  • автоматическое следование перенаправлениям
  • проверки на принятие изображения на основе content-type и content-length

Я проверил два случая.

Случай 1: прямой внутренний запрос

Валидатор запросил:

Скачать инструмент