Skip to content

fix(security): allowlist sort в листинге «Товары категории» - #933

Merged
biz87 merged 1 commit into
betafrom
fix/issue-918-category-products-sort
Oct 19, 2026
Merged

biz87 merged 1 commit into
betafrom
fix/issue-918-category-products-sort

Conversation

@Ibochkarev

Copy link
Copy Markdown
Member

Описание

В листинге «Товары категории» неизвестное значение sort уходило в ORDER BY как msProduct.{sort}. xPDO в sortby() отсекает только ;, union, sleep и benchmark, поэтому запятая и подзапрос проходили. Достаточно менеджера с view_document и правом смотреть категорию.

CategoryProductSort выбирает выражение только из колонок опций и связей грида, extra-полей msProductData с именем-идентификатором и фиксированной карты встроенных колонок. menuindex и effective_menuindex сортируются прежним выражением эффективного индекса. Всё остальное, включая preview_url и category_name (они собираются в PHP), сводится к этому же индексу.

longtitle, alias, parent, deleted, hidemenu сортируются по msProduct. new, popular, favorite, image и thumb сортируются по Data. Раньше часть этих имён падала в msProduct.{name}, хотя new лежит в Data и является зарезервированным словом MySQL.

Если sort пришёл не строкой, контроллер подставляет menuindex. dir по-прежнему только ASC или DESC.

Тип изменений

  • Исправление бага (non-breaking change)
  • Новая функциональность (non-breaking change)
  • Breaking change (изменение, ломающее обратную совместимость)
  • Рефакторинг (без изменения функциональности)
  • Документация
  • Другое (опишите):

Связанные Issues

Closes #918

Как это было протестировано?

  • php -l на изменённых PHP-файлах.
  • CategoryProductSortTest: вся карта встроенных колонок, колонка опции и extra-поле Data, неизвестное значение равно маркеру эффективного menuindex и не попадает в выражение.
  • CategoryProductsDataColumnsTest.

PHPStan и ESLint не запускал: Vue не менялся. Полный composer ci:php на этой машине раньше падал на трёх проверках HeadlessStorefrontErrorsTest (токен корзины), к этому diff они не относятся.

  • Ручное тестирование
  • Автоматические тесты (composer ci:php / composer test, npm run lint:ci, composer stan / GitHub Actions CI)
  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: ветка fix/issue-918-category-products-sort от beta (7f26ddb6)
  • MODX: не поднимался
  • PHP: 8.2+ (локально 8.5.8)

Скриншоты (если применимо)

До После

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность
  • Лексиконы добавлены на двух языках (ru/en)
  • PHPStan проходит без новых ошибок (composer stan / CI job PHPStan)
  • ESLint проходит без ошибок (npm run lint:ci для Vue)
  • Обновлён CHANGELOG.md (для значимых изменений)

Дополнительные заметки

Новых строк для пользователя нет. CHANGELOG по правилам репозитория пишется на релизе.

Ревью попросило не ограничиваться поиском текста return \$effectiveMenuindexSql в файле. Сравнение с маркером эффективного индекса теперь делает CategoryProductSort::expression(), и его вызывает mapSortField().

Готового payload в описании нет.

…918)

Неизвестное поле сортировки больше не попадает в ORDER BY: xPDO пропускает запятую и подзапрос.
@Ibochkarev
Ibochkarev requested a review from biz87 October 18, 2026 17:32
@biz87
biz87 merged commit 199e7be into beta Oct 19, 2026
6 checks passed
@biz87
biz87 deleted the fix/issue-918-category-products-sort branch October 19, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] SQL-инъекция через sort в листинге «Товары категории» (mapSortField)

2 participants