rest 26.500.0: журнал аудита безопасности и курсорные ответы в V3
Обновление безопасности
Закрыта уязвимость или ослабленная проверка прав. Ставить в первую очередь.
REST завёл единый журнал того, что происходит с приложениями, правами и вебхуками, а установщик переехал с SQL-батчей на миграции ядра. Публичные REST-методы не тронуты — ломается внутреннее и V3-API, так что читать этот разбор стоит тем, кто пишет свои модули поверх rest, а не тем, кто дёргает crm.deal.add.
SecurityAuditLogger: кто и что сделал с интеграциями
Новый Bitrix\Rest\Internal\Service\Security\SecurityAuditLogger пишет события установки и удаления приложений, смены прав доступа, запроса / подтверждения / отклонения scope, операций с вебхуками, действий системного пользователя и авторизаций.
Проблема, которую это закрывает, знакома любому, кто разбирал инцидент на большом портале: приложение с широкими правами стоит, вебхук существует, а кто, когда и с какими правами их завёл — восстанавливается по косвенным признакам. Теперь у этих действий есть общий журнал.
Класс лежит в Internal — подписываться на него и вызывать напрямую из прикладного кода не стоит, контракт не публичный. Но события в журнале безопасности портала теперь приходят отсюда, и это полезно знать при расследовании.
Логгер прокинут в конструкторы хендлеров приложений и вебхуков как ?SecurityAuditLogger $securityAuditLogger = null (или со значением по умолчанию), так что старые new Handler() продолжают работать.
Что сломается
CRestApiServer::initRequestScope()получил второй обязательный аргументMethodDescription. Наследники, переопределяющие метод со старой сигнатурой, не встанут. Смысл изменения — scope запроса теперь считается по описанию метода, а не выводится из самого запроса.Internal\Entity\Integration\Integration::setQuery()ждёт?arrayвместо?string(и поле в конструкторе тоже сменило тип). Строку больше не проглотит — молчаливой деградации не будет, будет TypeError.V3\Interaction\Request\ServerRequest::getToken()исчез из паспорта API.IntegrationMapper::convertFromArray()/convertToArray()удалены.
Совместимо: LoadLimiter::is(), getResetTime(), getRestTime(), registerStarting(), registerEnding() перешли на ?string-параметры — вызовы с null перестали быть сюрпризом. У команд создания входящего вебхука (AbstractCreateIncomingWebhookCommand, CreateIncomingWebhookCommand, SystemIncomingWebhookCreator::create) добавился ?string $comment = null — теперь вебхуку можно оставить подпись, зачем он заведён.
V3: курсор вместо смещения
Появились TailResponse и CursorResponseDto — ответы с курсором и флагом hasMore, плюс DtoCollection::last().
Это тот же путь, которым уже прошли crm.item.list и прочие «быстрые» списки: offset-пагинация на больших выборках заставляет базу пересчитывать пропущенные строки, и чем дальше страница, тем дороже. Курсор запоминает позицию и не платит за хвост. last() в коллекции — как раз то, из чего этот курсор берётся.
Установщик
install/db/{mysql,pgsql}/*.sql удалены, InstallDB() зовёт installMigrations(). Схема — в install/migrations/tables.php, события и агенты — в events.php / agents.php, плюс migration_config.json. Для уже установленного модуля это рефакторинг, а не новая схема: накатывать ничего не нужно.
Что делать
- Проверьте свой код на наследование
CRestApiServerи на вызовыIntegration::setQuery()со строкой. - Если писали своё логирование установок приложений — сравните со списком событий
SecurityAuditLogger, возможно, велосипед можно убрать. - Для новых списков в V3 сразу берите
TailResponse/ курсор, а не смещение.