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

Lists 26.300.0–26.400.0: закрыты XSS в Живой ленте и удаление чужих процессов, notifyAdmin пишет только администраторам

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

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

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

Модуль lists вышел двумя версиями, 26.300.0 и 26.400.0, и обе закрывают дыры. В 26.300.0 закрыли XSS при создании процесса из Живой ленты и уведомления «администратору», которые уходили любому сотруднику с любой ссылкой. В 26.400.0 сотрудник больше не удалит бизнес-процесс чужого документа. Перед обновлением проверьте наследников действия «Создать элемент списка», свои вызовы notifyAdmin и шаблоны БП, которые сравнивают текст HTML-свойств.

Новое

Пишите в «Деньги» число без валюты (26.300.0)

BizprocDocument::updateDocument() вызывается, когда элемент списка меняет бизнес-процесс (например, действием «Изменение документа») или ваш код через сервис документов bizproc. Для свойств типа «Деньги» (S:Money) метод теперь сам дописывает к числу без валюты базовую валюту портала в формате сумма|валюта. Если у валюты десятичный разделитель не точка, сумма переписывается под него без разделителя тысяч. Готовое значение проверяет само свойство, и при ошибке в элемент уходит исходная строка. Строки с минусом и запись вида 1e3 метод не трогает, их собирайте в формате сумма|валюта сами. Значение, где валюта уже стоит после |, уходит как есть.

        <?php declare(strict_types=1);

use Bitrix\Main\Loader;

Loader::requireModule('bizproc');
Loader::requireModule('lists');

$documentId = \BizprocDocument::getDocumentComplexId('lists', 42); // тип инфоблока (у обычных списков lists) и ID элемента

// в свойство с кодом BUDGET уйдёт сумма с базовой валютой через «|»
\CBPRuntime::getRuntime()
    ->getDocumentService()
    ->updateDocument($documentId, ['PROPERTY_BUDGET' => '1500.50']);

    

Что заметят пользователи (26.300.0)

Двойной клик по «Сохранить» в форме добавления элемента больше не создаёт дубль. Скрипт шаблона проверяет поля, блокирует кнопку и отправляет форму один раз. Защита есть только в шаблоне .default компонента lists.element.edit и только для форм с formId, который начинается с lists_element_add_. Если у вас своя копия шаблона, перенесите в неё изменения script.js.

Что сломается

Допишите третий параметр в наследника «Создать элемент списка» (26.300.0)

У CBPCreateListsDocumentActivity появился свой метод prepareFieldsValues(array $documentType, array $values, ?array $documentFields = null): array, у родителя CBPCreateDocumentActivity параметров по-прежнему два. Если ваше действие в /local/activities/ наследует CBPCreateListsDocumentActivity и переопределяет этот метод с двумя параметрами, PHP остановится с fatal error из-за несовместимой сигнатуры, как только подключит файл действия.

Добавьте третий параметр и передайте его родителю, тогда поля документа не будут загружаться второй раз.

        <?php declare(strict_types=1);

CBPRuntime::getRuntime()->includeActivityFile('CreateListsDocumentActivity');

final class CBPVendorCreateListsDocumentActivity extends CBPCreateListsDocumentActivity
{
    protected function prepareFieldsValues(
        array $documentType,
        array $values,
        ?array $documentFields = null,
    ): array {
        $values['NAME'] = trim((string)($values['NAME'] ?? ''));

        return parent::prepareFieldsValues($documentType, $values, $documentFields);
    }
}

    

Проверьте свои вызовы notifyAdmin (26.300.0)

Компонент lists.element.edit предлагает написать администратору, когда константы шаблона БП не настроены и у пользователя нет прав администратора списка. AJAX-действие notifyAdmin теперь проверяет адрес и получателя и при отказе отвечает ошибкой (фраза LISTS_NOTIFY_ERROR). elementUrl должен быть путём от корня сайта с одним / в начале, без \, управляющих символов, кавычек и угловых скобок. Получатель userId должен быть администратором списка, то есть иметь полный доступ к инфоблоку, выданный лично (код U<id>), или быть активным пользователем в группе администраторов.

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

Если в параметре LIST_ELEMENT_URL компонента стоит абсолютный адрес вида https://..., уведомление уйдёт со ссылкой /<каталог>/https://..., потому что компонент приклеивает текущий каталог ко всему, что не начинается с /. Замените адрес на путь от корня сайта.

Шаблоны БП получат HTML-свойства без сущностей (26.300.0)

BizprocDocument::getDocument() после HTMLToTxt() прогоняет значения HTML-свойств, одиночных и множественных, через html_entity_decode(). Бизнес-процесс получает &, <, > и ' там, где раньше были &amp;, &lt;, &gt; и &#39;, а &nbsp; из визуального редактора становится неразрывным пробелом (U+00A0), который на глаз не отличить от обычного. Кавычки &quot; раскодировал ещё HTMLToTxt(), для них ничего не меняется. В текстах, куда шаблон подставляет такое свойство, амперсанды и угловые скобки станут обычными. Условия, которые сравнивали свойство со строкой в сущностях, перестанут срабатывать.

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

Что закрыли

  • 26.300.0. Создание процесса из Живой ленты (lists.live.feed) брало NAME, PREVIEW_TEXT и DETAIL_TEXT прямо из $_POST. Теперь из названия вырезаются теги, а из описания с визуальным редактором (USE_EDITOR=Y) удаляется активное содержимое: скрипты, обработчики событий, ссылки javascript:. Санитайзер подключён только здесь, сохранение основной формы lists.element.edit релиз не менял.
  • 26.300.0. notifyAdmin больше не отправит уведомление с произвольной ссылкой произвольному сотруднику.
  • 26.300.0. Файлы списков рабочих групп в CRM (lists.element.attached.crm) скачиваются по правам в группе, то есть по роли участника и только при включённых в группе «Списках».
  • 26.400.0. CLists::completeWorkflow() проверял права на элемент из elementId, а процесс удалял по workflowId из запроса, не сверяя их. Сотрудник с правами на один элемент мог удалить процесс любого документа портала, если знал ID процесса. Теперь killWorkflow() получает $documentId и возвращает ошибку (фраза BPCGDOC_INVALID_WF_MSGVER_1), если процесс принадлежит другому документу, а сам процесс остаётся на месте. Штатные lists.element.edit и lists.list шлют согласованную пару и разницы не заметят.

Если ваш контроллер удаляет процессы по ID из запроса, передавайте документ третьим аргументом так же, как теперь делает lists:

        <?php declare(strict_types=1);

namespace Vendor\Module\Application\Service;

use Bitrix\Main\Error;
use Bitrix\Main\Loader;
use Bitrix\Main\Result;

final class WorkflowRemover
{
    public function remove(string $workflowId, array $documentId, int $userId): Result
    {
        $result = new Result();
        Loader::requireModule('bizproc');

        $canDelete = \CBPDocument::canUserOperateDocument(
            \CBPCanUserOperateOperation::CreateWorkflow,
            $userId,
            $documentId,
        );
        if (!$canDelete) {
            return $result->addError(new Error('Access denied', 'ACCESS_DENIED'));
        }

        // без $documentId удалится любой процесс, чей ID прислали
        foreach (\CBPDocument::killWorkflow($workflowId, true, $documentId) as $error) {
            $result->addError(new Error((string)$error['message']));
        }

        return $result;
    }
}

    

Для своих форм, которые создают элементы инфоблока из POST, подойдёт приём из Живой ленты: strip_tags() для названия и CBXSanitizer с уровнем SECURE_LEVEL_LOW и applyDoubleEncode(false) для HTML. В Живой ленте чистка не зависит от модуля bitrix24, а админская форма инфоблока включает такой же CBXSanitizer только при установленном bitrix24.

Мелочи и находки

  • В форме создания процесса из Живой ленты у полей «Дата/время» только для чтения появились скрытые input, так что их значение уходит вместе с формой (26.300.0).
  • Если значение одиночного поля типа «Список» приходит в «Создать элемент списка» ассоциативным массивом, действие берёт его первый ключ (26.300.0).
  • Поле «Дата» или «Дата/время» в lists.field.edit со значением по умолчанию, пришедшим массивом, теперь сохраняется. Компонент берёт первый непустой элемент, а раньше отвечал ошибкой «Неверный формат поля „Значение по умолчанию“». Значение '0' теперь тоже проверяется как дата и получает эту ошибку (26.300.0). Прошлую правку компонента мы разбирали в lists 26.200.100.

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

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

Подписаться

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

lists 26.200.0 Безопасность Свежее

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

Дифф lists 26.200.0 весит около 420 КБ, и почти весь объём ушёл на фронтенд мастера запуска бизнес-процесса `lists.element.creation_guide`, которому добавили работу с клавиатуры и со скринридером. REST-методы `lists.*` строже проверяют разделы и права при переносе, обновление без `IBLOCK_SECTION_ID`…

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

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

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

1 мин
timemanmobile 26.400.0 Заметное Свежее

Timemanmobile 26.0.0–26.400.0: окно «Начало рабочего дня» и рабочие отчёты в мобильном Битрикс24

Новый модуль timemanmobile («Мобильный учёт рабочего времени») пришёл в коробочный Битрикс24 сразу пятью версиями: 26.0.0, 26.100.0, 26.200.0, 26.300.0 и 26.400.0. Он добавляет в мобильное приложение окно «Начало рабочего дня», рабочие отчёты, экран «Рабочие дни» и плашку рабочего дня. Все версии ст…

4 мин
tasksmobile 26.900.0 Заметное Свежее

Tasksmobile 26.900.0: новый чек-лист в приложении, фильтр на телефоне и кеш счётчиков «Сроков»

В tasksmobile 26.900.0 (сборка от 29 июля 2026 года) мобильный чек-лист задачи переписан, доска «Сроки» начала кешировать счётчики стадий, а приложение научилось добавлять наблюдателя по ссылке. Код интеграторов это задевает, только если он сам вызывает мобильные экшены модуля или подключает его JS-…

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

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

на связи

пишет…

Можно закрыть чат и перейти на другую страницу. Когда ответ будет готов, на кнопке Домового появится отметка.

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

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

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

Войти