Lists 26.200.0: REST списков строже проверяет разделы, а файлы в lib/ сменили регистр
Обновление безопасности
Закрыта уязвимость или ослабленная проверка прав. Ставить в первую очередь.
Дифф lists 26.200.0 весит около 420 КБ, и почти весь объём ушёл на фронтенд мастера запуска бизнес-процесса lists.element.creation_guide, которому добавили работу с клавиатуры и со скринридером. REST-методы lists.* строже проверяют разделы и права при переносе, обновление без IBLOCK_SECTION_ID больше не сбрасывает привязку к разделу, файлы в lib/ сменили регистр, а PNG-картинки удалены в пользу WebP. Deprecated нет, схема таблиц и имена индексов прежние.
Проверьте интеграции через REST lists.*
Entity\Element::getElementFields() и Entity\Section::getFields() раньше при любом обновлении записывали IBLOCK_SECTION_ID, и если ключ не передали, туда уходил 0, то есть привязка к корню списка. Теперь поле трогается, только если оно есть в запросе. Если интеграция полагалась на старое поведение, передавайте ноль явно. Для lists.element.update ключ читается из FIELDS, поэтому нужен FIELDS[IBLOCK_SECTION_ID] = 0. Для раздела ключ читается с верхнего уровня параметров, там нужен IBLOCK_SECTION_ID = 0.
Перенос между разделами проверяется строже:
- целевой раздел берётся из
FIELDS.IBLOCK_SECTION_IDилиIBLOCK_SECTION_ID, должен быть числом и принадлежать тому же инфоблоку, иначеAccess denied; lists.element.updateпри смене раздела требует праваElementRight::ADDв целевом разделе,lists.section.updateтребуетSectionRight::ADD;- если целевой раздел совпадает с текущим, ключ перемещения отбрасывается;
- в
lists.section.addиlists.section.updateполеFIELDS.IBLOCK_ID, не совпадающее с инфоблоком запроса, тоже даётAccess denied, аIBLOCK_IDиCHECK_PERMISSIONSизFIELDSпри записи раздела игнорируются.
Права при изменении и удалении раздела теперь считаются по самому разделу (SECTION_ID или SECTION_CODE), а не по переданному в запросе IBLOCK_SECTION_ID.
Чтение тоже поменялось:
- из пользовательского фильтра
lists.element.getбольше не проходятCHECK_PERMISSIONS,PERMISSIONS_BYиMIN_PERMISSIONс любыми префиксами, аIBLOCK_IDи=IBLOCK_TYPEсервис ставит сам; lists.section.getтак же игнорирует в фильтреIBLOCK_ID,CHECK_PERMISSIONS,PERMISSIONS_BYиMIN_PERMISSIONи ставитIBLOCK_IDсам;- в выборку передаётся
CHECK_PERMISSIONS = 'Y', если право пользователя на список не одно из стандартных (CAN_READ,CAN_BIZPROC,CAN_WRITE,IS_ADMIN); - в
lists.section.getправоREADна раздел проверяется только приIBLOCK_SECTION_IDбольше нуля, явный0проверку не включает; вlists.element.getправоREADна элемент проверяется, только если в запросе естьELEMENT_IDилиELEMENT_CODE; lists.field.getтеперь явно требуетIblockRight::READ.
Прогоните свои сценарии перемещения и выборки под пользователем без прав администратора.
Проверьте права в CListPermissions
В CListPermissions::CheckAccess() поменялись три проверки:
- проверка типа сначала убеждается, что тип списочный:
lists, тип процессов из опцииlivefeed_iblock_type_idили тип с настроенными правами списков. ИначеWRONG_IBLOCK_TYPE; - администратор (
$USER->IsAdmin()) получаетIS_ADMINдо проверки прав списков. Раньше при пустых правах списков для типа он получалACCESS_DENIED; - проверка инфоблока, общая для обычных списков и списков в группах, отдаёт
WRONG_IBLOCK_TYPE, если такого типа инфоблоков нет вообще.
Код, который вызывает CheckAccess() без ID инфоблока и сравнивает результат с ACCESS_DENIED, для несписочных типов теперь увидит WRONG_IBLOCK_TYPE.
Поправьте пути, картинки и AJAX-вызовы
Файлы в lib/ переименованы в PascalCase: lib/bizprocdocument.php стал lib/BizprocDocument.php, lib/rest/restservice.php стал lib/Rest/RestService.php, lib/entity/element.php стал lib/Entity/Element.php, и так 39 файлов плюс 18 lang-файлов. В нашем эталоне теперь весь lib/ модуля в PascalCase. В include.php убрали ручные записи автозагрузки для Bitrix\Lists\Importer и BizprocDocumentLists, их теперь находит PSR-4, а глобальный BizprocDocument смотрит в lib/BizprocDocument.php.
Наш эталон стоит на регистронезависимой ФС, поэтому поведение на Linux по нему не проверить. Если установщик на Linux удалил старые пути, require по пути в нижнем регистре упадёт, так что проверьте свой код на прямые подключения файлов из lists/lib. Если держите ядро в git на маке, проверьте индекс: на регистронезависимой ФС git такие переименования не видит, у нас 57 путей lists пришлось фиксировать отдельным коммитом.
PNG-картинки модуля заменены на WebP, старые файлы удалены. Из публичной папки пропали /bitrix/images/lists/icons-files.png и /bitrix/images/lists/nopic_list_150.png, из шаблонов компонентов удалены bp-sprite.png, sprite.png, popup_notify_admin.png и фон мастера lists-el-cg-slider-bg.png. Свои шаблоны, которые на них ссылаются, получат 404.
В штатных шаблонах сменились имена AJAX-экшенов:
lists.controller.lock.unLock→lists.Lock.unLock;lists.controller.iblock.copy→lists.Iblock.copy;lists.controller.export→lists.Export.
У контроллеров модуля в .settings.php указан defaultNamespace \Bitrix\Lists\Controller, сам файл в релизе не менялся. Работают ли старые имена, дифф не показывает. Если ваш JS зовёт экшены lists по старым именам, проверьте вызовы или переходите на новые.
Учтите переезд установщика на миграции
install/db/{mysql,pgsql}/{install,uninstall}.sql удалены. DoInstall() зовёт installMigrations(), DoUninstall() зовёт uninstallMigrations($dropTables), где флаг берётся из savedata. Четыре таблицы (b_lists_permission, b_lists_field, b_lists_socnet_group, b_lists_url) теперь описаны в install/migrations/tables.php, регистрация обработчиков событий переехала из install/index.php в install/migrations/events.php. Схема таблиц и имена индексов прежние. Миграция задаёт уникальному индексу b_lists_socnet_group имя ux_b_lists_socnet_group_1, но по коду main в эталоне это имя используется только на MySQL, а на PostgreSQL ядро строит имя само, и выходит прежнее ux_b_lists_socnet_group_iblock_id_socnet_role.
Комментарий в events.php объясняет, почему часть классов обработчиков записана строкой с ведущим \, а часть через ::class. Имя класса хранится в b_module_to_module.TO_CLASS дословно, и унификация сломала бы отписку на порталах, установленных старыми версиями. Если переводите свой модуль на миграции, не приводите имена классов обработчиков к одному виду: пишите их так же, как они уже записаны в TO_CLASS у ваших установок.
Подсветите поле с ошибкой в мастере запуска
В Bitrix\Lists\Api\Service\WorkflowService два метода теперь кладут в ошибки валидации данные ['parameter' => ..., 'templateId' => ...]. Это getParameterValuesFromRequest(array $request, int $elementId) для параметров шаблона (возвращает GetParameterValuesResponse) и setConstants(array $request) для констант (возвращает Response). Мастер запуска по этим данным переводит фокус на поле с ошибкой. Ошибки без ключа parameter данных не несут, а startWorkflows() по-прежнему создаёт ошибки без данных. Оба ответа наследуют Bitrix\Main\Result, так что в своём коде данные читаются обычным образом:
<?php declare(strict_types=1);
use Bitrix\Main\Result;
function collectInvalidParameters(Result $response): array
{
$invalid = [];
foreach ($response->getErrors() as $error) {
$data = $error->getCustomData();
if (is_array($data) && isset($data['parameter'])) {
$invalid[$data['templateId']][] = $data['parameter'];
}
}
return $invalid;
}
// $workflowService: экземпляр \Bitrix\Lists\Api\Service\WorkflowService
$invalid = collectInvalidParameters(
$workflowService->getParameterValuesFromRequest($request, $elementId),
);
Сам мастер lists.element.creation_guide получил новый модуль src/a11y.js на 469 строк. Он подключает ui.a11y и хелперы BX.Bizproc.A11y из расширения bizproc.a11y, в разметке появились role="heading", aria-level и data-testid на шагах и формах. Модуль bizproc для компонента необязателен. Без него хелперов нет, и мастер, по словам комментария в коде, остаётся «mouse-only».
Мелочи и находки
unserialize()получил['allowed_classes' => false]в пяти местах:Copy\Implement\Iblock,Copy\Integration\Group,Copy\Integration\GroupStepper,Update\LivefeedIndexItemиIntegration\Socialnetwork\Log(там разбираютсяPARAMSзаписи ленты).CListFieldвставляет отсутствующую строку метаданных вb_lists_fieldчерезSqlHelper::prepareMerge()(приватныйmergeToStorage(), upsert поIBLOCK_IDиFIELD_ID). Существующую строку по-прежнему обновляет сыройUPDATE b_lists_field, теперь вынесенный вupdateMetadata(). Вместе со старым$DB->Add()ушёл комментарий"ID" => 1, //This makes Oracle version happy.BizprocDocument::updateDocument()пишет свойства типаS:DiskFileвнутри\Bitrix\Disk\Integration\FileDiskProperty::runInWorkflowWriteContext(), если модульdiskподключается и класс существует.CHTTP::urlAddParams(),urlDeleteParams()иURN2URI()в компонентах списков заменены наBitrix\Main\Web\UriсaddParams(),deleteParams()иtoAbsolute(). Опцииskip_emptyиencodeстарых вызовов в новый код не переехали.- Комментарии в
src/a11y.jsиsrc/index.jsописывают, как ставится фокус. Заголовок шага получает фокус с паузой, потому что слайдер ставит свой начальный фокус. В Firefox фрейм слайдера получает фокус ещё на полсекунды позже, поэтому попытки повторяются почти пять секунд. Повторная привязка обработчика «would turn one keypress into two calendars». - Порядок контейнеров шагов в шаблоне мастера менять нельзя, бандл находит их по позиции (комментарий ссылается на
#fillStepsвsrc/index.js). - В нашем эталоне lang-файл для
lib/Copy/Integration/Group.phpлежит вlang/{en,ru}/lib/copy/Integration/Group.php, с каталогомcopyв нижнем регистре. - Появились казахские переводы для
lists.live.feedи мастера, но только в публичных копиях компонентов вbitrix/components/. - Дата сборки 14 июля 2026.
Что делать
- Прогоните REST-интеграции со списками, особенно
lists.element.updateиlists.section.updateбезIBLOCK_SECTION_IDи переносы между разделами под обычным пользователем. - Поищите в шаблонах ссылки на
icons-files.png,nopic_list_150.pngи спрайты lists в PNG. - Проверьте
require/includeфайловbitrix/modules/lists/lib/по старым путям и JS-вызовыlists.controller.*. - Если сравниваете результат
CListPermissions::CheckAccess()с конкретными константами, проверьте ветки для администратора и несписочных типов.