lists · Универсальные списки 26.200.0 Безопасность

Lists 26.200.0: REST списков строже проверяет разделы, а файлы в lib/ сменили регистр

6 мин чтения
Узнавайте о ломающих изменениях Битрикса раньше, чем они доедут до прода: свежие разборы — в канале @bxmax_updates

Обновление безопасности

Закрыта уязвимость или ослабленная проверка прав. Ставить в первую очередь.

Дифф 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.

Что делать

  1. Прогоните REST-интеграции со списками, особенно lists.element.update и lists.section.update без IBLOCK_SECTION_ID и переносы между разделами под обычным пользователем.
  2. Поищите в шаблонах ссылки на icons-files.png, nopic_list_150.png и спрайты lists в PNG.
  3. Проверьте require/include файлов bitrix/modules/lists/lib/ по старым путям и JS-вызовы lists.controller.*.
  4. Если сравниваете результат CListPermissions::CheckAccess() с конкретными константами, проверьте ветки для администратора и несписочных типов.

Новая версия вышла — разбор уже в Telegram

В канале @bxmax_updates публикуем каждый свежий разбор: что сломается, что устарело и что появилось в API. Узнаете до того, как обновите прод.

Подписаться

Читайте дальше

lists 26.200.100 Рутинное Свежее

Lists 26.200.100: настройки поля списка принимаются только массивом

Патч в одну строку, собран 10 сентября. Компонент `lists.field.edit` при сохранении поля берёт `USER_TYPE_SETTINGS` из POST, только если там массив. Строку или любой другой скаляр он заменяет на `null`. Если ваш кастомный шаблон отправляет настройки пользовательского типа одной строкой, до ядра они…

1 мин
timeman 26.350.0 Заметное Свежее

Timeman 26.350.0: план дня пишется в нужную запись, блоки БП возвращают Saved

В timeman 26.350.0 для коробочного Битрикс24 блоки «Сохранить план на день» и «Сохранить отчёт сотрудника за день» из нового конструктора бизнес-процессов научились писать в заданную запись рабочего дня, оставлять Markdown как есть и сообщать, сохранилось ли (у отчёта новые настройки в конструкторе,…

2 мин
rpa 26.300.0 Безопасность Свежее

Rpa 26.300.0: права на перемещение элементов наконец проверяются

До RPA 26.300.0 `UserPermissions::canMoveItem()` сразу отвечал `true`, и любой сотрудник, кроме экстранет-пользователей, мог перетащить любой элемент на любую стадию, а права стадии на перемещение не учитывались. Теперь права проверяются, а тем, кто может только смотреть, `rpa.item.get` и `rpa.item….

3 мин
booking 26.500.100 Заметное Свежее

Booking 26.500.100: addList отвечает ошибкой, когда не создал ни одной брони, а четыре колонки дат стали DATETIME

В коробочный Битрикс24 пришёл booking 26.500.100 с двумя правками. AJAX-экшен `booking.api_v1.Booking.addList` теперь возвращает ошибку, если не создал ни одной брони. Апдейтер переводит четыре колонки дат с `TIMESTAMP` на `DATETIME`, и в `install/migrations/tables.php` они объявлены через `datetime…

3 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…
Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти