landing 26.900.0: undo/redo закрыли от инъекции PHP, execute стал final
Обновление безопасности
Закрыта уязвимость или ослабленная проверка прав. Ставить в первую очередь.
Главное в релизе — не новые фичи, а ужесточение истории правок. Действия undo/redo теперь проходят обязательную проверку на PHP-открывающий тег, а метод execute() сделан final, чтобы проверку нельзя было обойти переопределением. Плюс удалён контроллер AiBlocks, появившийся всего два релиза назад.
История правок: gate, который нельзя обойти
BaseAction::execute() стал final и делегирует в protected doExecute(). У всех конкретных действий execute переименован в doExecute. Перед делегированием стоит проверка:
final public function execute(bool $undo = true): bool
{
if (ActionParamsGuard::containsUnneutralizedPhpOpenTagDeep($this->params)) {
return false;
}
// ... XSS-аудит объявленных HTML-ключей
return $this->doExecute($undo);
}
Новый ActionParamsGuard::containsUnneutralizedPhpOpenTagDeep() рекурсивно обходит всё дерево параметров действия, включая вложенные MULTIPLY-элементы, и ищет неэкранированный <? в любом строковом листе. Комментарии в коде называют это fail-closed RCE-маркером, а final объясняют прямо: ни один шаг не должен дойти до своего сток-метода в обход гейта.
Почему это важно понимать, а не просто поставить обновление. История правок лендинга — это сохранённые параметры действий, которые потом применяются заново. Всё, что доехало до записи в историю, рано или поздно будет исполнено при откате. Значит, история — такой же вход недоверенных данных, как форма, только с отложенным исполнением. И final здесь не про стиль: любой наследник, переопределивший execute(), автоматически становился дырой, поэтому возможность переопределения убрали физически.
Тот же мотив рядом: в публичном просмотре (landing.pub/class.php) появились getDevicePreviewParentOrigin() и sanitizeOrigin() — query-параметр landing_device_preview принимается только в виде scheme://host[:port], без путей и лишнего. Плюс JS device_preview/responder.js и sandbox_shim.js.
Что сломается
BaseAction::execute()—final. Свои действия истории с переопределённымexecuteне соберутся. Переносите логику вdoExecute(); это ровно то, чего от вас хотят — тело действия под гейтом, а не вместо него.Controller\AiBlocksудалён целиком (экшеныmagicSiteStart/Resume/Status,changeAiSiteStart/Resume/Status,convert). ВController\CopilotдобавилисьconfigureActions()иmagicSiteStatusAction. Контроллер прожил ровно от 26.700.0 до 26.900.0 — хорошая иллюстрация, почему на свежие AI-контроллеры не стоит завязываться сразу.- Удалены
AI\SiteBuilder\Dto\DevContextDto,Service\DevContextService,Storage\ContextStorageInterface,Storage\OptionContextStorage— тоже приехали в 26.700.0 и тоже прожили два релиза.
В api.diff много изменений сигнатур Block::*, но это в основном косметика: array() → [], уточнение типов до ?string / ?Landing. getLandingRowByBlockId по-прежнему @deprecated.
Модерация темы и подбор домена
Развитие AI-сайтов продолжается:
- Модерация:
Dto\ModerationVerdictDtoс тремя состояниями (isAllowed,isHardBlock,isSoftBlock), схемаCopilot\Connector\Schema\AiSiteModerationVerdict, шагиRequestModerateAiSiteTopicиRequestModerateChangeAiSiteTopic. Тема сайта проверяется до генерации. Три состояния вместо булева — это возможность «мягко» притормозить сомнительное, а не только рубить. - Домен:
AI\SiteBuilder\Domain\AiSiteDomainPicker, шагTaskResolveAiSiteDomain, уEnhancedInputDtoпоявилисьgetAiDomains(),getCategory(),getTitle(). Адрес сайта тоже подбирается генерацией. - Починка блоков:
Copilot\Services\AiBlockLazyRepairService,HtmlBlock\CoverageRepairer,Manifest\RepoManifestMerger,HtmlBlock\NodeTagger::tagLeafTextNodes(). Сгенерированная разметка не всегда полностью корректна с точки зрения редактора — эти классы приводят её в рабочий вид уже после генерации. - Тулы ассистента:
SearchDeletedLandingSitesToolиRestoreLandingSiteTool— поиск и восстановление удалённых сайтов.
Схема БД не менялась.
Что делать
- Свои
History\Action— переименоватьexecuteвprotected doExecute, иначе модуль не встанет. - Найти обращения к
Controller\AiBlocksиDevContext*— этого больше нет. - Если вы делаете свою систему undo/redo с сохранением параметров — посмотрите на
ActionParamsGuardкак на образец: отложенное применение сохранённого ввода требует проверки на входе И на применении.