iblock · Информационные блоки 26.100.0 Безопасность

Iblock 26.100.0: файловые поля в БП только по ID, REST v3 для элементов

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

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

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

Iblock 26.100.0 (сборка от 14 сентября 2026) закрывает две дыры: подстановку путей, URL и массивов файлов в файловые поля через документ бизнес-процесса и обход прав при inline-редактировании цен в админке. Первая правка сломает шаблоны БП и свои активити, которые пишут в поле «Файл» ссылку или путь. Ещё в релизе первый REST v3-контроллер модуля и шаблоны каталога, переделанные под клавиатуру и экранные дикторы.

Новое

Читайте элементы через REST v3

Контроллер Bitrix\Iblock\Infrastructure\Rest\Controller\Element даёт два метода, iblock.element.get и iblock.element.list. Оба только читают и работают с инфоблоками, у которых REST_ON = Y, на остальные отвечают ошибкой «Restricted iblock». По коду сервиса нужен ещё символьный код API. Без API_CODE ORM-сущность инфоблока не соберётся, и придёт Unable to compile iblock entity.

Поля отдаются по белому списку: id, iblockId, name, iblockSectionId и properties, где свойства лежат по коду со значениями id, value, description. Фильтровать можно по всем четырём скалярным полям, сортировать по всем, кроме iblockId. В list фильтр по iblockId обязателен, в get инфоблок передаётся параметром iblock. Раздел 0 приходит как null, лимит по умолчанию 50.

        curl -s -X POST "https://portal.example.ru/rest/api/1/<secret>/iblock.element.list" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": [["iblockId", 12], ["iblockSectionId", 34]],
    "select": ["id", "name", "properties"],
    "order": {"name": "ASC"},
    "pagination": {"limit": 20}
  }'

    

Для одного элемента вызовите iblock.element.get с телом {"iblock": 12, "id": 345}. REST v3 и более строгие права приехали и в catalog, разбор в catalog 26.500.0.

Сохраняйте inline-цены публичной командой

Bitrix\Iblock\Public\Command\Catalog\SaveInlinePricesCommand сохраняет цены и закупочные цены так же, как inline-редактирование списка в админке. Каждый элемент пишется в своей транзакции. Ошибки приходят с кодами NO_BASE_PRICE, SAVE_FAILED и CATALOG_NOT_INSTALLED, ID элемента лежит в customData['ELEMENT_ID']. Права команда не проверяет, это делает вызывающий код. Какие элементы можно править из списка, подскажет Bitrix\Iblock\Public\Provider\Catalog\InlineEditTargetProvider. Его getEditableIblockIds() возвращает инфоблок списка и SKU-инфоблок его каталога, getProductIdsWithOffers() возвращает товары с активными ТП.

Каталог работает с клавиатуры и с экранным диктором

Под доступность переделаны системные шаблоны catalog.element, catalog.item, catalog.section, catalog.smart.filter и iblock.vote (bootstrap_v4), catalog.element, catalog.item, catalog.section и catalog.section.list (store_v3, store_v3_menu), catalog.compare.result и catalog.compare.list (.default). Для покупателя изменилось:

  • карточка в списке раскрывается и при фокусе с клавиатуры, раскрытой бывает только одна;
  • кнопки количества, стрелки галереи, миниатюры, кнопки покупки и заголовки свойств в фильтре стали <button>, до них доходит Tab;
  • у полей «от/до» в фильтре появились скрытые подписи для экранного диктора;
  • в таблице сравнения пустая ячейка озвучивается как «Нет значения», а строка с названиями товаров видна и в режиме «только различающиеся».

Клавиатуру и озвучку даёт расширение ui.a11y (BX.UI.Accessibility.FocusZone, FocusTrap, LiveAnnouncer, FocusNavigator). Без него страница работает, пропадают только эти функции. Шаблоны подключают расширение в component_epilog.php, потому что при попадании в кеш тело шаблона не выполняется, а в композите оно лежит в динамической зоне. В своих шаблонах подключайте его там же.

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

Передавайте в файловые поля БП только ID

CIBlockDocument::UpdateDocument() и CreateDocument() теперь принимают в файловые поля только ID из b_file, числом или строкой из цифр. Путь на сервере и URL отбрасываются молча. В UpdateDocument последствия хуже. Если ни одно значение не прошло проверку, поле получает del => Y, и текущий файл элемента удаляется. Эта ветка была и раньше, но теперь в неё попадают пути и URL.

Ключ, в значении которого на любой глубине есть массив с tmp_name или old_file, теперь выбрасывается целиком, необъявленный PROPERTY_VALUES тоже. Ключ PROPERTY_<CODE|ID> активного файлового свойства обрабатывается как файл, какой бы тип ни стоял в полях документа.

По комментариям в коде, строку CFile::MakeFileArray() прочитал бы как локальный путь или скачал бы по URL, а CFile::SaveFile() копирует tmp_name и удаляет файл из old_file. Через поля документа и ключ PROPERTY_VALUES можно было прицепить к элементу любой файл с сервера, заставить портал скачать URL или удалить чужой файл.

Сломаются шаблоны БП, которые пишут в поле «Файл» элемента ссылку или путь строкой, свои активити и код, который так же вызывает эти методы. Сохраните файл сами и передайте ID. Документ запишет свою копию файла новой записью в b_file, поэтому исходную запись после вызова удалите. Для множественного свойства передайте массив ID. Файлы, которых в нём нет, SetPropertyValuesEx() удалит, так что список заменяет текущие файлы целиком.

        <?php

declare(strict_types=1);

namespace Vendor\Bizproc;

use Bitrix\Main\SystemException;

final class WorkflowFileAttacher
{
    public function __construct(private readonly \CBPDocumentService $documentService)
    {
    }

    /** С iblock 26.100.0 документ принимает в файловые поля только ID из b_file. */
    public function attach(array $documentId, string $propertyCode, string $source): void
    {
        // $source берите из доверенного места: строка из формы даст ту же дыру, что закрыли в ядре
        $file = \CFile::MakeFileArray($source);
        if (!is_array($file) || empty($file['tmp_name'])) {
            throw new SystemException("Файл не получен: {$source}");
        }

        $fileId = (int)\CFile::SaveFile($file, 'iblock');
        if ($fileId <= 0) {
            throw new SystemException("Файл не сохранён: {$source}");
        }

        try {
            $this->documentService->UpdateDocument($documentId, ['PROPERTY_' . $propertyCode => $fileId]);
        } finally {
            // документ хранит свою копию файла, исходная запись в b_file не нужна
            \CFile::Delete($fileId);
        }
    }
}

    

В активити сервис берётся из $this->workflow->GetService('DocumentService'), ID документа из $this->GetDocumentId().

Проверьте свой CSS и JS поверх bootstrap_v4 и store_v3

Это касается тех, кто вешал стили и скрипты на системные шаблоны каталога, не копируя их в шаблон сайта. Скопированные шаблоны обновление не трогает.

  • У JCCatalogItemBootstrapV4 удалены hoverOn, hoverOff, onFocus, onBlur и captureMousePosition. Наведение теперь обрабатывают onPointerEnter, onPointerMove и onPointerLeave, фокус внутри карточки (focusin/focusout на самой карточке) обрабатывают новые onCardFocusIn и onCardFocusOut. Прямой замены у onFocus, onBlur и captureMousePosition нет, обработчики focus/blur с поля количества сняты.
  • JCSmartFilter.prototype.selectDropDownItem удалён из bootstrap_v4 (в .default остался). Выбор в выпадающем списке идёт через selectDropDownValue и closeDropDownPopup.
  • В разметке span и div интерактивных элементов стали button, ссылка покупки a.product-item-detail-buy-button тоже. Списки свойств и диапазонов цен ul.product-item-detail-properties > li в карточке товара стали dl > div с dt/dd, точки .product-item-detail-properties-dots убраны. a.product-item-image-wrapper в карточке списка стал div, а ссылка ушла внутрь, в a.product-item-image-link. У меток и кольца скидки убран title. В таблице сравнения появился <thead>, а в catalog.compare.result onclick выбора свойств переехал со span на чекбокс.
  • В store_v3 миниатюры галереи div.product-detail-slider-controls-image и div.catalog-section-item-slider-controls-image стали button.

Автотесты по таким селекторам тоже упадут. В шаблонах появилось около сотни data-testid, к ним тесты и стоит привязать.

Проверьте свои скрипты inline-цен

В iblock_element_admin.php и iblock_list_admin.php право на цену проверялось по инфоблоку списка, а не по инфоблоку элемента. CATALOG_PRICE_ID из POST уходил в CPrice::Update() и CPrice::Delete() без проверки, чья это цена. Теперь права проверяются по инфоблоку цели, ID цены другого товара или другого типа цены отбрасывается, а строки не из инфоблока списка и не из SKU-инфоблока его каталога пропускаются. Цены разбираются из $_POST['FIELDS'][<row>][CATALOG_GROUP_<N>_custom], прямые $_POST['CATALOG_PRICE'] и CATALOG_CURRENCY больше не читаются. При SKU и новой карточке (USE_NEW_CARD) закупочная цена из строки товара сохраняется в выбранное торговое предложение.

В тех же списках поменялись права документооборота. «Изменить» появилось у опубликованного элемента для тех, кто может перевести его в другой статус, а активация, транслитерация кода и сброс счётчика остались только при праве на статус от 2.

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

  • Формы элемента в админке и iblock.element.add.form передают в БП Bitrix\Bizproc\Starter\Enum\ManualStartSurface без проверки class_exists. В эталоне это перечисление появилось в bizproc 26.1400.0, так что bizproc обновляйте не позже iblock.
  • catalog.smart.filter при переходе на Uri::addParams() потерял опцию skip_empty. В FILTER_URL и FILTER_AJAX_URL теперь могут оставаться пустые параметры вроде bxajaxid=. Если разбираете эти ссылки в своём коде, проверьте.
  • В catalog.section/bootstrap_v4 у варианта раскладки 3 (четыре карточки в ряд) класс col-6 col-md-3 сменился на col-6 col-lg-3. На ширине 768–991 px в ряду теперь две карточки вместо четырёх.
  • Прошлая версия, 26.0.100, собрана за четыре дня до этой и запретила восстанавливать объекты из USER_TYPE_SETTINGS_LIST, разбор в iblock 26.0.100.

Устаревшие и удалённые API в этой версии

Символ Статус Чем заменять
JCCatalogItemBootstrapV4.prototype.hoverOn() Удалено JCCatalogItemBootstrapV4.prototype.onPointerEnter()
JCCatalogItemBootstrapV4.prototype.hoverOff() Удалено JCCatalogItemBootstrapV4.prototype.onPointerLeave()
JCCatalogItemBootstrapV4.prototype.captureMousePosition() Удалено —
JCCatalogItemBootstrapV4.prototype.onFocus() Удалено —
JCCatalogItemBootstrapV4.prototype.onBlur() Удалено —
JCSmartFilter.prototype.selectDropDownItem() Удалено JCSmartFilter.prototype.selectDropDownValue()

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

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

Подписаться

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

iblock 26.0.100 Безопасность

Iblock 26.0.100: ORM-поле USER_TYPE_SETTINGS_LIST больше не восстанавливает объекты

Сборка от 10 сентября 2026, содержательная правка в ней одна. `Bitrix\Iblock\PropertyTable` теперь десериализует поле `USER_TYPE_SETTINGS_LIST` (колонка `USER_TYPE_SETTINGS`) с запретом классов. Если вы пишете свои пользовательские типы свойств инфоблока и храните в настройках обычные массивы, для в…

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

Landing 26.1300.200–26.1600.0: закрыты дыры с PHP и правами групп, поля редактора стали ES-классами

С прошлого разбора вышли четыре версии landing: 26.1300.200, 26.1400.0, 26.1500.0 и 26.1600.0. В каждой закрыты дыры, от сборки PHP-тега при импорте сайта до лишних прав у участников групп соцсети. Попутно в режиме Битрикс24 превью черновика переехало на маршрут раздела «Сайты», а поля редактора ста…

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

Calendar 26.300.0: закрыты дыры в правах на календари и переговорки, дельта в REST

Calendar 26.300.0 закрывает три дыры в правах: перенос события в чужой календарь без права на добавление, подмену чужой брони переговорки через `LOCATION[’OLD’]` или `room_event_id` и добавление в участники проектов, где пользователь не состоит. Для интеграций в `calendar.event.get` появилось инкрем…

2 мин
blog 26.600.0 Заметное Свежее

Blog 26.600.0: тег кеша для важных сообщений и исправленные права в уведомлениях

Blog 26.600.0 ничего не ломает и базу не трогает. Разработчику он даёт тег кеша `blogpost_important_all` и метод, который считает, сколько секунд осталось до ближайшей отложенной публикации важного сообщения. `bitrix:blog.blog` в папке модуля больше не перебирает все посты блога ради списка авторов,…

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

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

на связи

пишет…

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

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

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

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

Войти