# 🔍 АНАЛИЗ БЕЗОПАСНОСТИ РАЗДЕЛОВ С ОДИНАКОВЫМИ НАЗВАНИЯМИ В КАБИНЕТАХ > **Дата:** 2025-09-19 > **Контекст:** 4 типа кабинетов (SELLER, FULFILLMENT, WHOLESALE, LOGIST) с одинаковыми названиями разделов --- ## 🚨 КЛЮЧЕВЫЕ ПРОБЛЕМЫ ### 1. ДУБЛИРОВАНИЕ МАРШРУТОВ БЕЗ ЗАЩИТЫ **Текущая структура:** ``` ГЛОБАЛЬНЫЕ (БЕЗ ЗАЩИТЫ) КАБИНЕТНЫЕ (С ЗАЩИТОЙ) /economics/ → /seller/economics/ /partners/ → /fulfillment/partners/ /messenger/ → /wholesale/messenger/ /market/ → /logistics/market/ ``` **Проблема:** Глобальные маршруты доступны ВСЕМ авторизованным пользователям независимо от их роли. ### 2. WRAPPER-КОМПОНЕНТЫ С ДИНАМИЧЕСКИМ РЕНДЕРИНГОМ **Пример: EconomicsPageWrapper** ```typescript export function EconomicsPageWrapper() { const { user } = useAuthContext() // Роутинг по типу организации switch (user.organization.type) { case 'SELLER': return case 'FULFILLMENT': return case 'WHOLESALE': return case 'LOGIST': return } } ``` **Риски:** - ❌ Пользователь может получить доступ к чужим компонентам через глобальный маршрут `/economics/` - ❌ Нет проверки прав доступа на уровне маршрута - ❌ Логика безопасности размазана между маршрутами и компонентами ### 3. ОБЩИЕ КОМПОНЕНТЫ ДЛЯ ВСЕХ РОЛЕЙ **Примеры проблемных компонентов:** - `PartnersDashboard` - используется всеми ролями без дифференциации - `MessengerDashboard` - единый компонент для всех типов организаций - `MarketDashboard` - общий маркет для всех **Что происходит внутри:** ```typescript // MessengerDashboard использует GET_MY_COUNTERPARTIES const counterparties = counterpartiesData?.myCounterparties || [] ``` **Проблема:** Один компонент пытается обслужить разные бизнес-логики для разных типов организаций. ### 4. ИЗОЛЯЦИЯ ДАННЫХ НА УРОВНЕ API **Хорошо:** API возвращает только `myCounterparties` - контрагентов текущей организации **Плохо:** Но доступ к компонентам не ограничен по ролям на уровне UI --- ## ⚠️ КОНКРЕТНЫЕ РИСКИ ### СЦЕНАРИЙ АТАКИ 1: Обход защиты через глобальные маршруты ``` 1. Пользователь SELLER авторизован 2. Заходит на /economics/ (вместо /seller/economics/) 3. EconomicsPageWrapper показывает SellerEconomicsPage 4. Но через манипуляции может получить доступ к данным других ролей ``` ### СЦЕНАРИЙ АТАКИ 2: Доступ к функционалу других ролей ``` 1. Логист заходит на /partners/ 2. Видит PartnersDashboard со своими данными 3. Но интерфейс может содержать функции для других ролей 4. Потенциальная утечка бизнес-логики ``` ### СЦЕНАРИЙ АТАКИ 3: Путаница в данных ``` 1. Пользователь с несколькими ролями (если такое возможно) 2. Заходит на глобальный маршрут 3. Непредсказуемое поведение wrapper-компонентов 4. Отображение некорректных данных ``` --- ## ✅ ПРАВИЛЬНОЕ РЕШЕНИЕ ### ВАРИАНТ 1: УДАЛИТЬ ГЛОБАЛЬНЫЕ МАРШРУТЫ **Преимущества:** - ✅ Невозможно обойти защиту - ✅ Четкая изоляция кабинетов - ✅ Простота понимания структуры **Недостатки:** - ❌ Нужно обновить все ссылки в приложении - ❌ Может сломать закладки пользователей ### ВАРИАНТ 2: ЗАЩИТИТЬ ГЛОБАЛЬНЫЕ МАРШРУТЫ ```typescript // /app/economics/page.tsx export default function EconomicsPage() { const { user } = useAuthContext() // Автоматический редирект на правильный кабинет if (user?.organization?.type) { redirect(`/${user.organization.type.toLowerCase()}/economics/`) } return
Загрузка...
} ``` **Преимущества:** - ✅ Обратная совместимость - ✅ Автоматическая навигация - ✅ Защита от неавторизованного доступа ### ВАРИАНТ 3: РОЛЬ-СПЕЦИФИЧНЫЕ КОМПОНЕНТЫ Вместо общих компонентов создать специфичные для каждой роли: ``` PartnersDashboard → SellerPartnersDashboard → FulfillmentPartnersDashboard → WholesalePartnersDashboard → LogistPartnersDashboard ``` **Преимущества:** - ✅ Четкая бизнес-логика для каждой роли - ✅ Невозможно показать чужой функционал - ✅ Легче тестировать и поддерживать --- ## 🛡️ РЕКОМЕНДУЕМАЯ АРХИТЕКТУРА ### 1. СТРУКТУРА МАРШРУТОВ ``` /seller/ ├── home/ (✅ protected with useRoleGuard) ├── economics/ (✅ protected with useRoleGuard) ├── partners/ (✅ protected with useRoleGuard) └── messenger/ (✅ protected with useRoleGuard) /fulfillment/ ├── home/ (✅ protected with useRoleGuard) ├── economics/ (✅ protected with useRoleGuard) ├── partners/ (✅ protected with useRoleGuard) └── messenger/ (✅ protected with useRoleGuard) ❌ УДАЛИТЬ ИЛИ ЗАЩИТИТЬ: /economics/ /partners/ /messenger/ /market/ ``` ### 2. ЗАЩИТА НА УРОВНЕ LAYOUT ```typescript // /app/seller/layout.tsx export default function SellerLayout({ children }) { useRoleGuard('SELLER') // Защита всего кабинета return ( {children} ) } ``` ### 3. СПЕЦИФИЧНЫЕ КОМПОНЕНТЫ ```typescript // Вместо общего PartnersDashboard export function SellerPartnersDashboard() { // Логика только для селлеров } export function FulfillmentPartnersDashboard() { // Логика только для фулфилмента } ``` --- ## 📋 ПЛАН ДЕЙСТВИЙ ### ЭТАП 1: НЕМЕДЛЕННО (Сегодня) 1. **Добавить редиректы в глобальные страницы:** ```typescript // /app/economics/page.tsx if (user?.organization?.type) { redirect(`/${user.organization.type.toLowerCase()}/economics/`) } ``` 2. **Добавить useRoleGuard в wrapper-компоненты:** ```typescript export function EconomicsPageWrapper() { // Добавить проверку перед switch if (!user?.organization?.type) { redirect('/login') } } ``` ### ЭТАП 2: КРАТКОСРОЧНО (1-3 дня) 1. **Создать layout-защиту для каждого кабинета** 2. **Провести аудит всех ссылок на глобальные маршруты** 3. **Создать карту редиректов для обратной совместимости** ### ЭТАП 3: ДОЛГОСРОЧНО (1-2 недели) 1. **Разделить общие компоненты на роль-специфичные** 2. **Удалить глобальные маршруты после миграции** 3. **Создать автоматические тесты для проверки доступа** --- ## 🎯 ИТОГ **Текущая ситуация:** Опасная архитектура с возможностью обхода защиты через глобальные маршруты. **Решение:** Либо полностью удалить глобальные маршруты, либо добавить автоматические редиректы на роль-специфичные страницы. **Приоритет:** 🔴 КРИТИЧЕСКИЙ - исправить в течение 1-2 дней