Описание проблемы
CustomersController::getList принимает любые query-параметры filter_* и строит where([$fieldName.':LIKE' => ...]) без whitelist колонок.
formatCustomer не отдаёт token в списке, но фильтр filter_token=<prefix> позволяет oracle/сужение по секретному полю.
Тот же паттерн есть в Deliveries/Payments (ниже риск — нужен mssetting_save).
Шаги воспроизведения
Mgr с доступом к /api/mgr/customers (сейчас view_document, [Bug] Manager API: customers CRUD и category publish под view_document #378 ).
GET route=/api/mgr/customers&filter_token=<known_or_prefix>.
Список сужается до владельца token / подтверждает наличие префикса через LIKE.
Ожидаемое поведение
Whitelist разрешённых filter-полей (как для UI-фильтров). Секретные колонки (token, password, …) недоступны для фильтрации.
Фактическое поведение
// CustomersController.php ~67-75
if (str_starts_with ($ key , 'filter_ ' ) && !empty ($ value )) {
$ fieldName = substr ($ key , 7 );
// ...
$ c ->where ([$ fieldName . ':LIKE ' => "% {$ value }% " ]);
}
Окружение
MiniShop3: beta / Manager REST
MODX: 3.x
PHP: 8.2+
Дополнительный контекст
Связь с dual token model (#369 ) и утечкой token в profile (#410 ) / order update.
Описание проблемы
CustomersController::getListпринимает любые query-параметрыfilter_*и строитwhere([$fieldName.':LIKE' => ...])без whitelist колонок.formatCustomerне отдаётtokenв списке, но фильтрfilter_token=<prefix>позволяет oracle/сужение по секретному полю.Тот же паттерн есть в Deliveries/Payments (ниже риск — нужен
mssetting_save).Шаги воспроизведения
/api/mgr/customers(сейчасview_document, [Bug] Manager API: customers CRUD и category publish под view_document #378).GETroute=/api/mgr/customers&filter_token=<known_or_prefix>.Ожидаемое поведение
Whitelist разрешённых filter-полей (как для UI-фильтров). Секретные колонки (
token,password, …) недоступны для фильтрации.Фактическое поведение
Окружение
Дополнительный контекст
Связь с dual token model (#369) и утечкой token в profile (#410) / order update.